关系数据库
关系数据库中名词术语之间的对应关系:
关系模型理论 | 关系数据库管理系统(SQL) | 文件系统 |
---|---|---|
关系 relation | 表 table | 文件 set of records |
属性 attribute | 列 column | 字段 field |
元组 tuple | 行 row | 记录 record |
关系模式 schema | 表头 table heading | 记录型 type of record |
码 key | 主码 primary key | - |
候选码 candidate key | 唯一码 unique | - |
关系数据结构及形式化定义
域(Domain)
域(Domain)是具有相同数据类型的值的集合。
示例:
- 整数、实数
- 特定范围整数:
[18, 60]
- 字符串集合:
char(25)
- 枚举类型:
{ '男', '女' }
同一域中元素互不相同。
笛卡尔积
给定域 ,其笛卡尔积为:
特性:
- 每个元素称为 元组
- 基数计算:若各域基数分别为 ,则总基数为
关系(Relation)
可参考《离散数学》笔记。
- 关系(Relation):逻辑上表示为二维表,数学上定义为笛卡尔积的子集。
- 元组(Tuple):表中的一行,代表一个具体的记录。
- 属性(Attribute):表中的一列,对应某一特定字段。
- 域(Domain):属性值的取值范围,例如性别属性的域可以是「男, 女」。
符号约定
- 关系用大写字母 表示。
- 元组用小写字母 表示。
- 属性用 表示。
- 域用 表示。
关系可以有三种类型:
- 基本关系(基本表或基表):实际存在的表,是实际存储数据的逻辑表示。
- 查询表:查询结果对应的表,结果数据不需要持久存储。
- 视图表:由基本表或其他视图表导出的表,是虚表,结果数据也不需要持久存储。
查询表与视图表的区别
两者都有对应的数据库查询操作,但查询表对应的查询请求不需要保存在数据库中,而视图表对应的查询请求需要持久保存在数据库中。
说明:
- 上面所说的「表」的概念,一般只在关系数据库管理系统(即 SQL 语言)中使用
- 关系模型是一种逻辑数据模型,不涉及数据的物理存储,在关系模型理论中,其数据结构只有「关系」
- 在关系模型上进行数据操纵,其操作结果也构成一个「关系」(也可以通俗地称为「结果关系」「临时关系」或「中间关系」)
关系可以是一个无限集合,定义关系的笛卡尔积不满足交换律。因此使用「关系」来作为关系数据模型的数据结构时,需添加约束「关系是一个有限子集」与「笛卡尔积满足交换律」。
从而关系模型数据结构的「关系」具有以下性质:
- 列同质性:每一列中的分量来自同一个域,且具有相同的数据类型。
- 属性唯一性:每个属性必须有唯一的名称,即使不同属性可能共享相同的域。
- 列无序性:属性的排列顺序无关紧要,可以通过属性名访问特定列。
- 行唯一性:任意两个元组在候选码上的取值不能相同。
- 行无序性:元组的排列顺序无关紧要,可通过指定条件访问特定行。
- 原子性:每个分量必须是不可再分的最小数据项。
码的分类与作用
码(Key)是关系中用于唯一标识元组的属性或属性组,分为以下几类:
- 候选码(Candidate Key):能唯一标识元组的最小属性组,简称码。
- 主码(Primary Key):从候选码中选出的一个作为主码。
- 外码(Foreign Key):引用其他关系主码的属性。
- 全码(All-Key):当所有属性共同构成候选码时称为全码。
每个关系至少有一个候选码,这是关系模型的基本特性。
候选码中的诸属性称为该关系的主属性(prime attribute)。不包含在任何候选码中的属性称为非主属性(non-prime attribute)。
数据完整性约束
关系模型定义了三类完整性约束,以确保数据的正确性和一致性:
- 实体完整性(Entity Integrity):主码中的属性不能取空值,且主码值必须唯一。2. 参照完整性(Referential Integrity):外码要么为空,要么必须引用被参照关系中已存在的主码值。
- 用户定义完整性(User-Defined Integrity):根据具体应用需求定义的约束条件,例如非空、唯一性或取值范围。
实体完整性
- 规则:主码中的属性不能取空值(NULL),且主码值必须唯一。
- 目的:保证每个元组的唯一性。
- 示例:
1
2
3
4
5
6CREATE TABLE Students (
学号 INT PRIMARY KEY, -- 整数类型;主码:唯一非空
姓名 VARCHAR(50) NOT NULL, -- 可变长度字符串,最多 50 字符;非空
性别 CHAR(1), -- 固定长度字符串,1 字符
年龄 INT
);
参照完整性
- 规则:外码(Foreign Key)要么为空,要么必须引用被参照关系中已存在的主码值。
- 目的:维护关系间的引用一致性。
- 示例:
1
2
3
4
5
6
7CREATE TABLE Enrollments (
学号 INT,
课程号 INT,
成绩 DECIMAL(4,2), -- 小数类型,总位数 4 位,小数 2 位
FOREIGN KEY (学号) REFERENCES Students(学号), -- 学号必须存在于 Students 表中,或为空
FOREIGN KEY (课程号) REFERENCES Courses(课程号) -- 课程号必须存在于 Courses 表中,或为空
);
用户定义完整性
- 规则:根据具体应用需求定义的约束条件,例如非空、唯一性或取值范围。
- 示例:
1
2
3
4
5CREATE TABLE Courses (
课程号 INT PRIMARY KEY,
课程名 VARCHAR(100) UNIQUE, -- 唯一(候选码)
学分 INT CHECK (学分 BETWEEN 1 AND 4) -- 取值范围(微积分:你好)
);
关系模式与关系实例
- 关系模式(Relation Schema):描述关系的结构,包括属性集合、域及完整性约束。
- 形式化表示:
- :关系名
- :属性集合
- :域集合
- :属性到域的映射
- :完整性约束条件
- 形式化表示:
- 关系实例(Relation Instance):某一时刻关系的具体内容,即元组集合。
关系模式通常可以简记为 或 ,其中 为属性名, 为属性名集合, 为关系名。
关系操作
关系模型支持两类基本操作:查询和更新。这些操作可以进一步分解为以下五种基本关系操作:
- 选择(Selection):从关系中筛选符合条件的元组。
- 投影(Projection):从关系中提取指定的属性列。
- 笛卡尔积(Cartesian Product):生成两个关系的所有组合。
- 并(Union):合并两个关系的元组集合。
- 差(Difference):从一个关系中移除另一个关系的元组。
graph TD
A[关系操作] --> B[查询操作]
A --> C[更新操作]
B --> D[选择]
B --> E[投影]
B --> F[连接]
C --> G[插入]
C --> H[删除]
C --> I[修改]
关系代数
概述
核心概念
关系代数(Relational Algebra)是一种抽象的查询语言,用关系运算表达对关系的操作:
- 运算对象和结果均为关系
- 包含集合运算和专门关系运算
- 表达式可表示数据查询、插入、删除和修改
运算分类
graph TD
A[关系运算] --> B[集合运算]
A --> C[专门关系运算]
B --> D[并/差/交/笛卡尔积]
C --> E[选择/投影/连接/除]
关键特性
- 集合操作:操作对象和结果都是元组集合
- 基本运算:并、差、笛卡尔积、选择、投影
- 运算符要求:需同时掌握执行条件和结果模式
基本运算体系
集合运算
- 并运算(Union)
- 前提条件:同类关系(同目且属性域相同)
- 数学表达:
- 操作符:R union S
- 特性:交换律、结合律
- SQL 例子:
1
2
3
4
5-- 选出所有选修了「数据库」或「数据结构」课程的学生
-- SC (Student Course) 表示学生选课关系表(学号,课程号)
SELECT 学号 FROM SC WHERE 课程号 = '数据库'
UNION
SELECT 学号 FROM SC WHERE 课程号 = '数据结构';
- 差运算(Difference)
- 数学表达:
- 操作符:R except S
- 典型应用:排除特定数据
- SQL 例子:
1
2
3
4-- 选出所有选修了「数据库」但未选修「数据结构」课程的学生
SELECT 学号 FROM SC WHERE 课程号 = '数据库'
EXCEPT
SELECT 学号 FROM SC WHERE 课程号 = '数据结构';
- 笛卡尔积(Cartesian Product)
- 结果模式: 列关系
- 数学表达:
- 操作符:R product S
- 注意:同名属性需重命名
- SQL 例子:
1
2-- 选出所有学生选修的课程
SELECT * FROM Students, SC WHERE Students.学号 = SC.学号;
专门关系运算
- 选择(Selection)
- 前提条件:选择条件 是一个只能由关系属性名、常量、运算符组成的逻辑表达式
- 数学表达:
- 操作符:R where F
- 执行逻辑:
1
2
3
4result = []
for t in R:
if F(t) == True:
result.append(t) # 修改为将符合条件的元组添加到结果列表 - SQL 例子
1
2-- 选出所有年龄大于 18 岁的学生
SELECT * FROM Students WHERE 年龄 > 18;
- 投影(Projection)
- 前提条件:属性集合 是关系 的属性集的子集
- 数学表达:
- 操作符:R[A1, A2, …, An]
- 去重机制:自动消除重复元组
- SQL 例子:
1
2-- 选出所有学生的学号和姓名
SELECT 学号, 姓名 FROM Students;
记号系统与核心概念
符号 | 含义 |
---|---|
大写字母表示属性名,小写字母表示属性值。例如:用 表示属性名,用 或 表示属性 的值 | |
大写字母表示关系中的一个属性组/属性集 | |
大写字母表示关系名,代表一个关系,或该关系的一个实例 | |
关系模式:关系名 , 关系中的属性集合 | |
关系中的元组 | |
元组 在属性(集) 上的取值 |
设关系模式为 :
- 它的一个关系(实例)设为
- 表示 是 中的一个元组
- 表示元组 中相应于属性 的一个分量(元组 在属性 上的值)
- 若 ,其中 是来自于 中的属性,则 称为「属性列」或「属性组」或「属性集」。
- 表示元组 在属性组 上诸分量的集合。
- 则表示从 中去掉 后剩余的属性组。
元组连接
元组连接:设 为 目关系, 为 目关系,令 ,则 表示来自不同关系的元组拼接。
- 这是一个 列的元组,前 列来自 中元组 ,后 列来自 中元组 。
- 可简记为
象集
象集(Image Set):给定一个关系 ,其中 为属性组, 为属性组 定义域上的一个值, 在 中的象集定义为 ,表示 中属性组 上值为 的元组在属性组 上的值集合。
假设有一张订单表(相当于关系 ):
订单号() | 菜品() | 数量 |
---|---|---|
1001 | 汉堡 | 2 |
1001 | 薯条 | 3 |
1002 | 炸鸡 | 1 |
1003 | 汉堡 | 1 |
1003 | 薯条 | 2 |
- 属性组 = 订单号(单一属性)
- 属性组 = 菜品 + 数量(组合属性)
现在要查询订单号 1001 对应的所有菜品和数量,这就是象集的典型应用场景。
象集生成过程:
- 过滤:在订单表中筛选出 的元组
订单号() 菜品() 数量 1001 汉堡 2 1001 薯条 3 - 投影:提取这些元组的 属性(菜品 + 数量)
菜品() 数量 汉堡 2 薯条 3 - 结果:这个投影结果就是订单号 1001 的象集
对应 SQL 查询语句:
1 | SELECT 菜品, 数量 FROM Orders |
象集的本质:相当于数据库中的「条件投影」操作。可以理解为——当我们要回答「某个 值对应的 值有哪些?」这类问题时,就是在求象集。
关系模式语义
- 同名同义原则:属性名相同则语义与域相同
- 重命名机制:通过赋值运算解决异名同义问题
扩展运算
交运算
交运算(Intersection)是关系代数中的一种集合运算,用于找出两个关系中共有的元组。
- 前提条件:两个关系必须是同类关系
- 具有相同的目(属性数量相同)
- 对应属性取自同一个域
- 数学表达:
- 操作符:R intersect S
- 特性:
- 满足交换律:
- 满足结合律:
- 实现方式:交运算可以通过差运算实现
假设我们有两个表,分别记录了两场派对的参与者名单:
- 派对 A 的参与者名单:
姓名 | 年龄 | 性别 |
---|---|---|
小明 | 20 | 男 |
小红 | 22 | 女 |
小刚 | 21 | 男 |
- 派对 B 的参与者名单:
姓名 | 年龄 | 性别 |
---|---|---|
小红 | 22 | 女 |
小丽 | 23 | 女 |
小刚 | 21 | 男 |
计算过程:
- : 只参加派对 A 的人
姓名 年龄 性别 小明 20 男 - : 只参加派对 B 的人
姓名 年龄 性别 小丽 23 女 - 最终交集 : 同时参加了两场派对的人
姓名 年龄 性别 小红 22 女 小刚 21 男
SQL 语句示例:
1 | -- 查询同时喜欢苹果和香蕉的学生学号 |
连接运算
连接运算是关系代数中的重要扩充运算,用于将两个关系根据特定条件合并。
-连接
-运算
- 定义:
- 操作符 :(R product S) where F
- 特点:
- 从笛卡尔积中选取满足特定条件的元组
- 可使用各种比较运算符( 等)
等值连接
等值连接
- 定义:当 为 时的连接称为等值连接
- 特点:保留重复列
假设我们有两个表:
- 学生表(Student):记录学生的学号和姓名。
学号 | 姓名 |
---|---|
1 | 小明 |
2 | 小红 |
3 | 小刚 |
- 选课表(CourseSelection):记录学生选课的情况,包括学号和课程。
学号 | 课程 |
---|---|
1 | 数学 |
1 | 英语 |
2 | 数学 |
4 | 物理 |
示例:找出学生及其选课情况。
1 | SELECT * |
结果:
学号_S | 姓名 | 学号_C | 课程 |
---|---|---|---|
1 | 小明 | 1 | 数学 |
1 | 小明 | 1 | 英语 |
2 | 小红 | 2 | 数学 |
解释:
- 条件是
S.学号 = C.学号
,所以只有学号相同的记录会被保留。 - 结果中仍然包含重复列(如
学号_S
和学号_C
)。
自然连接
自然连接
- 定义:特殊的等值连接,基于同名属性进行连接并去除重复列
- 操作符:R join S
- 特点:
- 同时从行和列的角度进行运算
- 结果关系模式为两个关系属性的并集
承接上面的示例:找出学生及其选课情况。
1 | SELECT * |
结果:
学号 | 姓名 | 课程 |
---|---|---|
1 | 小明 | 数学 |
1 | 小明 | 英语 |
2 | 小红 | 数学 |
解释:
- 自然连接会自动找到两个表中同名的列(这里是「学号」),并基于这些列进行等值连接。
- 结果中去掉了重复列(只有一个「学号」列)。
外连接
- 悬浮元组:在自然连接中被舍弃的不匹配元组
- 类型:
- 左外连接(⟕):保留左侧关系的悬浮元组
- 操作符:R left outer join S
- 右外连接(⟖):保留右侧关系的悬浮元组
- 操作符:R right outer join S
- 完全外连接(⟗):同时保留两侧的悬浮元组
- 操作符:R full outer join S
- 左外连接(⟕):保留左侧关系的悬浮元组
示例:找出所有学生及其选课情况(如果没有选课,则显示 NULL)。
1 | SELECT * |
结果:
学号_S | 姓名 | 学号_C | 课程 |
---|---|---|---|
1 | 小明 | 1 | 数学 |
1 | 小明 | 1 | 英语 |
2 | 小红 | 2 | 数学 |
3 | 小刚 | NULL | NULL |
解释:
- 左侧表(Student)中的所有记录都被保留。
- 如果某个学生没有选课(如小刚),则右侧表的字段显示为 NULL。
同理,右外连接和完全外连接的 SQL 语句与结果如下:
1 | SELECT * |
学号_S | 姓名 | 学号_C | 课程 |
---|---|---|---|
1 | 小明 | 1 | 数学 |
1 | 小明 | 1 | 英语 |
2 | 小红 | 2 | 数学 |
NULL | NULL | 4 | 物理 |
1 | SELECT * |
学号_S | 姓名 | 学号_C | 课程 |
---|---|---|---|
1 | 小明 | 1 | 数学 |
1 | 小明 | 1 | 英语 |
2 | 小红 | 2 | 数学 |
3 | 小刚 | NULL | NULL |
NULL | NULL | 4 | 物理 |
除运算
除运算是关系代数中用于处理「全部」类查询的重要运算。除运算的作用是从一个表中找出那些满足另一个表中「所有条件」的记录。
- 定义:
其中 是 在 中的象集
- 操作符:R divideby S
- 推导公式:
推导步骤:
- 计算最大可能结果集
- 计算
- 找出不符合条件的元组
- 投影得到不符合条件的 值集合
- 最终结果
假设我们有两个表:
- 学生选课表:
学号 | 课程 |
---|---|
1 | 数学 |
1 | 英语 |
1 | 物理 |
2 | 数学 |
2 | 英语 |
3 | 数学 |
- 课程表:
课程 |
---|
数学 |
英语 |
物理 |
如果我们想找出选修了所有课程的学生,可以用除运算:
1 | SELECT 学号 |
结果:
学号 |
---|
1 |
计算过程:
- 计算最大可能结果集 ,即所有可能的学生的学号
学号 1 2 3 - 使用笛卡尔积将学生与所有课程组结合起来,得到理想状态的选课表
学号 课程 1 数学 1 英语 1 物理 2 数学 2 英语 2 物理 3 数学 3 英语 3 物理 - 从理想选课表剔除实际选课表,得到不符合条件的学生
学号 课程 2 物理 3 英语 3 物理 - 投影得到不符合条件的学生学号
学号 2 3 - 最终结果为 减去不符合条件的学生学号
学号 1