【软考架构】关系数据库
关系数据库是目前应用非常广泛的数据库之一,有一套完整的理论支持。关系模型是关系数据库的基础,由关系数据结构、关系操作集合和关系完整性规则3部分组成。本文介绍关系模型的基本概念、关系代数、关系演算和关系数据库设计理论方面的内容。
关系模型的基本概念
关系的基本术语
作为系统架构设计师,理解关系数据库中的这些核心术语至关重要。它们构成了关系模型的理论基础和数据操作规则。以下是每个术语的详细解释:
-
属性 (Attribute)
- 定义: 关系(表)中的一列。它代表了实体的某个特征或描述性信息。
- 类比: 就像Excel表格中的列标题(如“员工ID”、“姓名”、“部门”、“工资”)。
- 关键点: 每个属性都有一个唯一的名称(列名)和一个定义其允许值范围的域(Domain)。
- 例子: 在
员工(员工ID, 姓名, 部门, 工资)
关系中,“员工ID”、“姓名”、“部门”、“工资”都是属性。
-
域 (Domain)
- 定义: 一个属性所有可能取值的集合。它定义了属性的数据类型、格式和约束(如取值范围、长度限制)。
- 目的: 确保属性的值具有意义、有效且可比较。域是数据完整性的基础。
- 例子:
员工ID
的域可能是“6位数字字符串”。姓名
的域可能是“长度不超过50的字符串”。部门
的域可能是集合 {‘研发部’, ‘市场部’, ‘销售部’, ‘财务部’}。工资
的域可能是“大于等于0的浮点数”。
-
目 或 度 (Degree / Arity)
- 定义: 一个关系中属性的数目。
- 关键点: 它描述了表的“宽度”或“列数”。
- 例子: 关系
员工(员工ID, 姓名, 部门, 工资)
的目(度)是4。
-
候选码 (Candidate Key)
- 定义: 关系中能够唯一标识每一行(元组)的最小属性集合。
- 关键特性:
- 唯一性 (Uniqueness): 关系中任意两个不同的元组,其候选码的值都不相同。
- 最小性 (Minimality): 候选码中的任何一个属性都不能被移除,否则唯一性将不再成立。即候选码是一个最小的、能唯一标识元组的属性集。
- 重要点: 一个关系可以有多个候选码。
- 例子: 在
员工(员工ID, 姓名, 部门, 工资)
关系中:员工ID
很可能是一个候选码(假设每个员工有唯一ID)。- 如果“姓名”在该公司内也保证唯一(现实中很少见),那么
姓名
也可能是另一个候选码。 - 如果
员工ID
是唯一的,那么{员工ID, 姓名}
虽然也能唯一标识元组,但不满足最小性(去掉“姓名”后员工ID
依然唯一),所以{员工ID, 姓名}
不是候选码。
-
主码 (Primary Key)
- 定义: 从所有候选码中选定一个,作为关系中唯一标识元组的主要依据。
- 关键点:
- 一个关系有且只有一个主码。
- 主码的属性值不能为空 (NOT NULL)。
- 主码是数据库实现参照完整性的基础。
- 选择原则: 通常选择最简单、最稳定(值不常变更)、业务含义明确的候选码作为主码。
- 例子: 在
员工
关系中,员工ID
通常被选为主码。
-
主属性 (Prime Attribute / Key Attribute)
- 定义: 包含在任何一个候选码中的属性。
- 关键点:
- 主属性是参与构成候选码的属性。
- 非主属性 (Non-prime Attribute / Non-key Attribute) 是不包含在任何候选码中的属性。
- 例子: 在
员工
关系中,如果员工ID
是唯一候选码(也是主码),那么员工ID
是主属性,姓名
、部门
、工资
是非主属性。如果姓名
也是一个候选码,那么员工ID
和姓名
都是主属性。
-
外码 (Foreign Key)
- 定义: 关系R中的一个属性(或属性集合)FK,其值必须匹配另一个关系S中某个元组的主码值(或者为空,如果允许的话)。
- 目的: 建立两个关系(表)之间的关联,实现参照完整性约束。FK的值要么是空(如果允许),要么必须在被参照关系S的主码列中存在对应的值。
- 关键点:
- FK 和它参照的 S 的主码必须定义在相同的域上。
- R 称为参照关系 (Referencing Relation)。
- S 称为被参照关系 (Referenced Relation) / 目标关系 (Target Relation)。
- 例子: 考虑两个关系:
部门(部门ID, 部门名称, 经理)
-部门ID
是主码。员工(员工ID, 姓名, 部门ID, 工资)
-员工ID
是主码。- 在
员工
关系中,部门ID
是一个外码 (FK),它参照部门
关系中的主码部门ID
。它表示“每个员工必须属于一个已存在的部门”(假设部门ID
在员工
表中不允许为空)。
-
全码 (All-key)
- 定义: 一种特殊的候选码,它由关系中的所有属性组成。
- 关键特性:
- 该关系中没有其他候选码(除了这个包含所有属性的候选码)。
- 唯一能唯一标识元组的方法是使用所有属性。
- 关系中不存在非主属性,因为所有属性都是主属性(它们构成了唯一的候选码)。
- 例子: 考虑一个表示“学生选课”的关系
选课(学生ID, 课程ID)
。假设一个学生可以选多门课,一门课可以被多个学生选,但每个学生每门课只能选一次(即不能重复选同一门课)。- 单个属性
学生ID
或课程ID
都不能唯一标识一行(因为一个学生对应多行,一门课也对应多行)。 - 只有
{学生ID, 课程ID}
这个属性组合才能唯一标识一个具体的选课记录。 - 这个关系没有其他候选码。
- 因此,
{学生ID, 课程ID}
是候选码(也是主码),并且它是全码。学生ID
和课程ID
都是主属性。
- 单个属性
-
笛卡儿积 (Cartesian Product)
- 定义: 两个集合(通常是两个关系)中所有可能有序对的集合。
- 数学表示: 设关系 R 有 m 个属性,k 个元组;关系 S 有 n 个属性,l 个元组。它们的笛卡儿积 R × S 是一个新关系:
- 属性: 包含 R 的所有属性 + S 的所有属性(共 m+n 个属性)。如果属性名有冲突,需要改名。
- 元组: 包含所有可能的组合,即 R 中的每一个元组与 S 中的每一个元组拼接在一起。共 k * l 个元组。
- 关键点:
- 笛卡儿积是关系代数中最基本的运算之一,是连接(JOIN)操作的基础。
- 其结果通常包含大量冗余和无意义的组合(尤其是在没有连接条件时)。
- 例子:
- R (A, B) = {(a1, b1), (a2, b2)}
- S (C, D) = {(c1, d1), (c2, d2)}
- R × S = {
(a1, b1, c1, d1),
(a1, b1, c2, d2),
(a2, b2, c1, d1),
(a2, b2, c2, d2)
}
总结关系图:
关系 (Relation) / 表 (Table)||-- 目/度 (Degree): 列的数量||-- 属性 (Attribute) 1..N: 列||-- 域 (Domain): 该列允许的值范围/类型||-- 元组 (Tuple) 1..M: 行 (未在问题中列出,但隐含存在)||-- 键 (Keys)||-- 候选码 (Candidate Key) 1..N: 最小唯一标识符集合| || |-- [选定的一个] --> 主码 (Primary Key): 主要的唯一标识符 (NOT NULL)| || |-- 主属性 (Prime Attribute): 属于任何候选码的属性||-- 外码 (Foreign Key): 引用其他关系主码的属性 (用于关联)||-- 全码 (All-key): 整个属性集是唯一的候选码 (所有属性都是主属性)||-- 操作 (Operations)||-- 笛卡儿积 (Cartesian Product): 两个关系的所有可能组合
理解这些术语是设计健壮、高效、符合范式的关系数据库模式的基础,也是理解SQL查询(特别是连接操作)和数据库约束(如实体完整性、参照完整性)的前提。作为系统架构师,你需要确保数据库设计正确地运用这些概念以满足业务需求和性能目标。
关系数据库模式
核心概念解析:
-
型 (Type/Schema) vs. 值 (Value/Instance):
- 型 (关系数据库模式): 这是数据库的结构蓝图或设计。它定义了数据库里有什么(有哪些表)、每个表的结构是什么样的(有哪些列/属性)、这些列的数据类型和约束是什么、表之间的关系如何(通过键)。它描述的是数据库的静态结构,是相对稳定、不经常变化的。
- 值 (关系数据库实例): 这是特定时间点数据库里存储的实际数据。它是符合模式定义的具体记录(行/元组)的集合。这个集合是动态变化的,随着数据的增删改查而不断更新。
- 类比: 想象一张表格。
- 型: 表格的标题行(定义了列名和数据类型),以及关于表格的说明(如主键、外键约束)。
- 值: 表格中填充的具体数据行。
-
关系数据库模式 (Relational Database Schema):
- 它是整个数据库所有关系模式 (Relation Schema) 的集合。
- 它还包含域 (Domain) 的定义。域是属性的取值范围或数据类型的抽象定义(例如:“正整数”、“长度不超过20的字符串”、“性别{‘男’,’女’}”)。
- 因此,关系数据库模式 = 域定义集合 + 关系模式集合。
-
关系模式 (Relation Schema) - 定义 R(U, D, dom, F):
- R: 关系名。代表一个具体的表(如
学生
,课程
,选课
)。 - U: 属性名集合。构成该关系的所有列的名称(如
{学号, 姓名, 系名, 年龄}
)。 - D: 域集合。这些属性所对应的域的集合。每个属性都关联一个域。
- dom: 属性向域的映像集合。这是一个映射函数,它精确地指定了属性 U 中的每个属性具体对应哪个域 D 中的域。这是定义属性数据类型和取值范围的关键部分。
- 例子解析: 在课程关系
C
中,PCno
(先修课程号)这个属性的值应该来自Cno
(课程号)这个域所定义的取值范围(即所有存在的课程号)。所以dom(PCno) = Cno
。这保证了先修课程号必须是实际存在的一门课的课程号。同时,教材强调,虽然PCno
的值域和Cno
相同,但属性名必须不同(因为关系模型要求属性名在同一个关系模式内唯一),所以必须通过dom
显式声明这种取值约束。
- 例子解析: 在课程关系
- F: 属性间数据的依赖关系集合。主要是函数依赖 (Functional Dependency) 等完整性约束规则(如“学号唯一确定一个学生姓名” ->
学号 -> 姓名
)。教材提到这部分在后续讨论。 - 简记法: R(U) 或 R(A₁, A₂, …, Aₙ)
- 这是最常见的表示法,只包含关系名和属性名集合。
- 域 (
D
)、属性到域的映射 (dom
) 以及依赖 (F
) 通常会在数据库管理系统 (DBMS) 中通过 数据类型声明 (如VARCHAR(20)
,INT
) 和 约束 (如PRIMARY KEY
,FOREIGN KEY
,UNIQUE
,CHECK
) 来实现。 - 属性名
A₁, A₂, ..., Aₙ
就是集合U
的元素。
- R: 关系名。代表一个具体的表(如
-
主码 (Primary Key):
- 在一个关系模式中,能唯一标识一条元组(一行记录)的最小属性集合。
- 表示法: 通常在关系模式简记法中,在作为主码的属性名下面加下划线。
- 例子解析:
S(Sno, Sname, SD, SA)
:Sno
(学号) 下加了下划线,表示它是学生表S
的主码,能唯一确定一个学生。C(Cno, Cname, PCno)
:Cno
(课程号) 是主码,能唯一确定一门课程。SC(Sno, Cno, Grade)
:(Sno, Cno)
(学号和课程号的组合) 是主码,因为一个学生选一门课只有一个成绩,这个组合能唯一确定一条选课记录。
-
外码 (Foreign Key):
- 一个关系模式 R1 中的属性(或属性集),它引用了另一个关系模式 R2 的主码。
- 外码的值必须在被引用的主码中存在(参照完整性约束),或者为空(如果允许空值)。
- 作用: 建立不同关系(表)之间的关联。
- 例子解析:
- 在选课关系
SC
中:Sno
是外码,它引用了学生关系S
的主码Sno
。这保证了选课记录中的学生必须是已存在的学生。Cno
是外码,它引用了课程关系C
的主码Cno
。这保证了选课记录中的课程必须是已存在的课程。
- 在课程关系
C
中:PCno
通过dom(PCno) = Cno
约束,也隐含地指向了本关系的主码Cno
(自引用)。这保证了先修课程号必须是本表中存在的一门课的课程号。
- 在选课关系
对教材示例的详细解读:
-
学生关系模式 S(Sno, Sname, SD, SA):
- 型: 定义了名为
S
的表结构,有四个属性:学号Sno
、姓名Sname
、系名SD
、年龄SA
。 - 主码:
Sno
(学号),唯一标识一个学生。 - 隐含的域/约束 (通过dom和DBMS实现):
Sno
可能是字符串类型且唯一;Sname
、SD
是字符串;SA
是整数类型且范围合理(如 >0)。 - 值 (实例): 某个时刻,这张表里存储的所有具体学生记录。
- 型: 定义了名为
-
课程关系模式 C(Cno, Cname, PCno), Dom(PCno)=Cno:
- 型: 定义了名为
C
的表结构,有三个属性:课程号Cno
、课程名Cname
、先修课程号PCno
。 - 主码:
Cno
(课程号),唯一标识一门课程。 - 关键约束:
Dom(PCno) = Cno
。这明确指定了PCno
这个属性的值域必须等同于Cno
属性的值域。也就是说:- 输入到
PCno
字段的值,必须是Cno
字段中已经存在的某个值(即某门已存在课程的课程号)。 - 这建立了课程表自身的参照完整性约束:一门课的先修课必须是系统中已有的另一门课(或者为空,如果允许)。
- 输入到
- 属性名唯一性: 即使
PCno
的值域和Cno
相同,也必须使用不同的属性名PCno
,不能直接命名为Cno
,否则在同一个表中就出现了两个同名的列,违反了关系模型的基本要求。
- 型: 定义了名为
-
学生选课关系模式 SC(Sno, Cno, Grade):
- 型: 定义了名为
SC
的表结构,有三个属性:学号Sno
、课程号Cno
、成绩Grade
。 - 主码:
(Sno, Cno)
。这表示需要同时使用学号和课程号才能唯一确定一条记录(一个学生选一门课,只有一个成绩)。 - 外码:
Sno
是外码,参照学生表S
的主码Sno
。确保选课记录中的学生是存在的。Cno
是外码,参照课程表C
的主码Cno
。确保选课记录中的课程是存在的。
- 隐含的域/约束:
Grade
可能是数值类型(如0-100的整数或浮点数)或等级类型(如A, B, C)。
- 型: 定义了名为
总结与要点:
- 数据库设计是核心: 关系数据库模式 (
型
) 是数据库设计的静态结构描述,是构建数据库的基础。 - 模式 vs. 实例: 严格区分数据库的结构 (
型
) 和 具体数据 (值
/实例
)。 - 关系模式是表的蓝图: 每个关系模式定义了一个表的结构(列名、数据类型/域、主键、外键、约束)。
- 完整定义 R(U, D, dom, F): 这是关系模式最严谨的理论定义,涵盖了所有必要信息。
- 实践中的简记 R(U): 实际设计和文档中最常用的是简记法
R(A₁, A₂, ..., Aₙ)
,主码属性加下划线。其他信息(域、dom
映射、F
依赖)通过DBMS的数据类型定义和约束(PRIMARY KEY
,FOREIGN KEY
,UNIQUE
,NOT NULL
,CHECK
)来实现。 - 主码: 保证记录的唯一性标识。
- 外码: 建立表间联系,维护数据一致性(参照完整性)。
SC
表完美展示了如何使用外键连接S
和C
表。 dom
的作用: 显式定义属性的数据类型和值范围约束,特别是当属性名与它引用的主键名不同时(如C
表中的PCno
)。
理解这些概念对于设计健壮、一致的关系数据库模式至关重要,这也是系统架构设计师在设计和评估系统数据层时必须掌握的基础知识。教材中的这个定义清晰地阐述了关系数据库的理论基石。
关系的完整性约束
核心目标: 完整性约束的核心目标是维护数据库中数据的正确性、有效性和一致性,防止对数据的意外破坏(非恶意破坏,如操作失误、程序逻辑错误等)。它定义了数据必须满足的条件。
三大类完整性约束解析:
-
实体完整性 (Entity Integrity)
- 核心思想: 保证关系(表)中的每个实体(记录)都是可唯一标识的。
- 规则:
- 每个基本关系(表)必须定义一个主键 (Primary Key)。
- 构成主键的所有属性(字段)的值,不能全部或部分为
NULL
(空值)。这是主键的非空性 (Non-null) 约束。 - 构成主键的所有属性(字段)的值组合,在整个关系(表)中必须是唯一的。这是主键的唯一性 (Uniqueness) 约束。
- 为什么重要? 想象一个学生表,如果没有主键(如学号),或者学号可以为空或重复,就无法准确、唯一地标识和定位一个特定的学生记录。这会导致数据混乱和操作歧义。
- 教材表示法: 主键属性在关系模式中用实下划线标识(如
员工号
)。 - DBMS 实现: 在创建表时,通过
PRIMARY KEY
约束定义。DBMS 会自动强制该属性的非空性和唯一性。
-
参照完整性 (Referential Integrity / 引用完整性)
- 核心思想: 维护表与表之间通过外键引用建立的关系的有效性。 保证一个表(子表/参照关系)中引用的另一个表(父表/被参照关系)的值是确实存在的。
- 规则 (形式化描述): 设
F
是基本关系R
(参照关系/子表)的一个外键 (Foreign Key),它对应于基本关系S
(被参照关系/父表)的主键Ks
。那么,对于R
中的每一个元组(记录):- 要么 该元组在
F
上的值 为空 (NULL
)(注意:F
的所有属性都为空)。 - 要么 该元组在
F
上的值 必须等于 关系S
中某个元组的主键Ks
的值。
- 要么 该元组在
- 关键点:
- 外键 (F): 子表中的一个属性(或属性集),其值必须匹配父表的主键值(或为空)。
- 被参照关系 (S): 拥有被引用主键的表。
- 参照关系 ®: 包含外键的表。
R
和S
可以是同一个表: 这就是自引用的情况(如教材后面提到的C(PCno)
引用C(Cno)
,员工表中“经理工号”引用本表的“员工号”)。- 空值处理: 规则允许外键为空(
NULL
),这通常表示“引用关系暂时不存在”或“未知”。例如,新员工尚未分配部门。
- 为什么重要? 防止出现“孤儿记录”或“无效引用”。例如:
- 在
Emp(部门号)
引用Dept(部门号)
的场景下:- 不允许在
Emp
表中插入一条记录,其部门号
的值在Dept
表中不存在(除非部门号
为NULL
)。 - 不允许删除
Dept
表中某个被Emp
表记录引用的部门(除非同时处理了所有引用它的员工记录,或者DBMS配置了级联操作)。 - 不允许修改
Dept
表中某个被引用的主键值(除非同时更新所有引用它的Emp
记录的外键值,或者DBMS配置了级联操作)。
- 不允许在
- 在
- 教材示例解析:
Emp(员工号, 姓名, 性别, 参加工作时间, 部门号)
Dept(部门号, 名称, 电话, 负责人)
- 外键:
Emp.部门号
是外键。 - 被参照关系:
Dept
。 - 参照关系:
Emp
。 - 规则:
Emp
表中每条记录的部门号
字段,要么是NULL
(表示员工暂未分配部门),要么必须是Dept
表中某个已存在的部门号
。
- 教材表示法: 外键属性在关系模式中用虚下划线标识(如
部门号
)。 - DBMS 实现: 在创建表时,通过
FOREIGN KEY
约束定义。DBMS 会自动检查插入、更新、删除操作是否违反规则。通常会涉及级联操作 (ON DELETE CASCADE
,ON UPDATE CASCADE
) 或限制 (RESTRICT
) 等选项来处理对被参照键的修改/删除。
-
用户定义完整性 (User Defined Integrity)
- 核心思想: 针对特定业务场景或应用逻辑,定义数据必须满足的语义规则。 这是对前两种通用完整性约束的补充。
- 规则: 由数据库设计者或应用开发者根据具体的业务需求定义。
- 涵盖范围广泛:
- 域完整性: 约束单个属性的取值范围或格式。这是最常见的用户定义完整性。
- 示例1:
性别
属性只能取'男'
或'女'
。 - 示例2:
年龄 (SA)
属性必须是正整数,且范围在16
到65
之间。 - 教材示例: 银行账户号必须在
100000
到999999
之间 (>=100000 AND <1000000
)。 - 教材示例: 实验室管理员基本薪资必须
>=2000
。
- 示例1:
- 元组完整性: 约束同一记录内多个属性值之间的关系。
- 示例:
开始日期
必须早于或等于结束日期
。 - 示例:
折扣率
大于0
时,折扣价
必须小于原价
。
- 示例:
- 更复杂的业务规则: 有时需要编写存储过程或触发器来实现。
- 域完整性: 约束单个属性的取值范围或格式。这是最常见的用户定义完整性。
- 为什么重要? 确保数据符合实际业务逻辑和规则,防止录入无效或无意义的数据。例如,年龄为负数、薪资低于最低标准、结束日期早于开始日期等都是业务上不允许的。
- DBMS 实现:
CHECK
约束: 最常用,直接在表定义时对属性或元组施加条件。NOT NULL
约束: 强制属性不能为空(严格来说也属于域完整性)。UNIQUE
约束: 强制属性(或属性集)值唯一(非主键唯一性)。DEFAULT
: 设置默认值。- 数据类型 (Data Type): 是最基础的域约束(如
INT
,VARCHAR(20)
,DATE
)。 - 触发器 (Triggers): 用于实现更复杂的、涉及多表或需要执行特定逻辑的规则。
- 存储过程 (Stored Procedures): 在应用层或数据库层封装数据操作逻辑时加入校验。
总结与关键点:
- 层级关系:
- 实体完整性 是关系(表)内部的唯一标识基础。
- 参照完整性 是关系(表)之间的引用有效性保证。
- 用户定义完整性 是具体业务语义的落地,作用于属性域、元组内或多表间复杂逻辑。
- 强制性与声明性: 这些约束通常由 DBMS 强制执行。数据库设计者通过 SQL DDL (数据定义语言) 声明 这些约束,DBMS 负责在数据操作(增删改)时自动检查,违反约束的操作会被拒绝。
- 数据质量的基石: 完整性约束是构建可靠、一致、可信赖数据库系统的核心机制。它们是数据库设计的关键环节,直接影响数据的质量和后续应用开发的复杂度。
- 区分“意外破坏”与“恶意破坏”: 完整性约束主要防止的是授权用户的操作失误、程序逻辑错误等导致的意外数据破坏。它不等同于安全性机制(如用户认证、授权、加密),后者是防止恶意用户的未授权访问和破坏。
- 实践意义: 对于系统架构设计师而言,深刻理解并能正确应用这三种完整性约束至关重要:
- 在设计数据库模式时,必须明确主键、外键和必要的业务约束 (
CHECK
)。 - 在评估数据库设计方案时,需要检查其完整性约束是否完备,能否有效保障核心业务规则。
- 在理解现有系统数据模型时,完整性约束是解读表间关系和业务规则的重要线索。
- 在进行数据迁移或集成时,需要确保源数据和目标模式的完整性约束兼容。
- 在设计数据库模式时,必须明确主键、外键和必要的业务约束 (
教材示例串联理解:
- 学生表
S(Sno, Sname, SD, SA)
:Sno
主键 (实体完整性),SA
(年龄) 可能需要用户定义完整性 (如SA BETWEEN 16 AND 30
)。 - 课程表
C(Cno, Cname, PCno)
:Cno
主键 (实体完整性),PCno
既是外键 (参照完整性 - 自引用到Cno
),其值域Dom(PCno)=Cno
本身也是一个用户定义的域完整性约束。 - 选课表
SC(Sno, Cno, Grade)
:(Sno, Cno)
主键 (实体完整性),Sno
外键 (参照S.Sno
),Cno
外键 (参照C.Cno
),Grade
可能需要用户定义完整性 (如Grade BETWEEN 0 AND 100
或Grade IN ('A','B','C','D','F')
)。
通过这三种完整性约束的协同作用,关系数据库能够有效地维护其数据的语义正确性和一致性,为上层应用提供可靠的数据基础。
关系运算
关系代数运算深度解析
关系代数是关系数据库的理论基础,其核心是通过一系列运算符对关系(即二维表)进行操作,且操作对象和结果均为集合。以下从运算特点、运算符分类入手,对各类运算进行详细解析,结合场景与示例说明其逻辑与应用。
一、关系操作的核心特点与运算符分类
- 核心特点:关系操作的本质是“集合操作”——无论是输入的关系(如表)还是输出的结果,都是元组(记录)的集合,因此操作具有集合的封闭性(结果仍为关系)。
- 运算符分类:
- 集合运算符:对应传统集合运算(并、交、差、广义笛卡儿积),基于元组的“属于”关系进行操作。
- 专门的关系运算符:关系数据库特有的运算(选择、投影、连接、除法等),可同时操作元组(水平方向)和属性(垂直方向)。
- 算术比较符(如>、<、=):用于定义操作条件(如选择、连接的筛选条件)。
- 逻辑运算符(如AND、OR、NOT):组合算术比较条件,增强条件的表达能力。
二、传统集合运算(水平方向操作)
传统集合运算基于集合论的基本操作,要求参与运算的关系具有相同的关系模式(即元数相同、属性名及类型一致),仅从“元组是否属于某集合”的角度操作(水平方向,即行层面)。
-
并(Union,R∪S)
- 定义:由属于R或属于S的所有元组组成的集合(自动去重,因集合元素唯一)。
- 前提:R和S必须同模式(如“学生表”和“学生表副本”)。
- 示例:若R是“一班学生”,S是“二班学生”,则R∪S是“一、二班所有学生”(无重复)。
-
差(Difference,R-S)
- 定义:由属于R但不属于S的元组组成的集合。
- 前提:R和S同模式。
- 示例:R是“所有选过课的学生”,S是“选过数学课的学生”,则R-S是“选过课但没选数学课的学生”。
-
交(Intersection,R∩S)
- 定义:由同时属于R和S的元组组成的集合。
- 前提:R和S同模式。
- 性质:可由基本运算导出(R∩S = R - (R - S)),因此不是基本运算。
- 示例:R是“男生”,S是“班干部”,则R∩S是“男生班干部”。
-
广义笛卡儿积(Extended Cartesian Product,R×S)
- 定义:将R(n目,即n个属性)和S(m目)的所有元组组合,形成一个(n+m)目的新关系,其中前n列是R的元组,后m列是S的元组。
- 结果规模:行数 = R的行数 × S的行数;列数 = R的列数 + S的列数。
- 示例:R(学生:学号,姓名)有2行,S(课程:课程号,课程名)有3行,则R×S有2×3=6行,列数为2+2=4(学号、姓名、课程号、课程名)。
- 作用:是连接运算的基础(连接是对笛卡儿积的筛选)。
三、专门的关系运算(水平+垂直方向操作)
专门的关系运算突破了传统集合运算的限制,可同时操作元组(水平)和属性(垂直),更贴合关系数据库的实际需求。
(一)5种基本关系运算(可导出其他所有运算)
-
投影(Projection,πₐ®,A为属性列)
- 定义:从关系R中选择部分属性列A,组成新的关系(垂直方向操作,即列层面)。
- 特点:结果的关系模式由A决定(列数减少),元组去重(因集合特性)。
- 示例:对“学生表(学号,姓名,性别,年龄)”做π₍学号,姓名₎®,结果为仅含“学号、姓名”两列的新表。
-
选择(Selection,σₚ®,P为条件)
- 定义:从关系R中筛选出满足条件P的元组(水平方向操作,即行层面)。
- 特点:结果的关系模式与R一致(列数不变),行数减少(仅保留符合条件的元组)。
- 条件P:由算术比较符和逻辑运算符组合而成(如“年龄>18 AND 性别=‘男’”)。
- 示例:σ₍年龄>18₎(学生表),结果为“所有年龄大于18岁的学生”。
-
并、差、广义笛卡儿积:前文已述,因不可被其他运算导出,故列为基本运算。
(二)其他导出运算
-
连接(Join)
连接是从两个关系的笛卡儿积中筛选满足条件的元组,本质是“有条件的笛卡儿积”。根据条件不同,分为三类:- θ连接:从R×S中选择“R的属性A与S的属性B满足θ关系(θ为>、<、≥、≤、=)”的元组,记为R⋈₍AθB₎S。
示例:R(学生:学号,姓名),S(选课:学号,课程号),θ连接“R.学号 = S.学号”,等价于筛选出学号匹配的元组。 - 等值连接:θ为“=”的θ连接,即选择A与B值相等的元组。
- 自然连接:特殊的等值连接,要求连接的属性组必须是两者共有的(如都有“学号”),且结果中自动去掉重复的属性列(只保留一组共有属性)。
示例:学生表(学号,姓名)与选课表(学号,课程号)自然连接后,结果含“学号,姓名,课程号”(仅保留一个“学号”),是实际中最常用的连接方式。
- θ连接:从R×S中选择“R的属性A与S的属性B满足θ关系(θ为>、<、≥、≤、=)”的元组,记为R⋈₍AθB₎S。
-
除(Division,R÷S)
- 场景:用于解决“查询满足‘所有条件’的元组”(如“选修了所有课程的学生”)。
- 前提:设R(X,Y)、S(Y,Z),其中Y是共有的属性组(如“课程”),X是目标属性(如“学生”),Z是其他属性。
- 定义:R÷S的结果是X的子集,其中每个x(X的分量)在R中的“象集”(即x对应的所有Y值的集合)必须包含S在Y上的投影(即S中所有Y值)。
- 示例:
- R(学生,课程):{(张三, 数学), (张三, 语文), (李四, 数学)}
- S(课程,教师):{(数学, 王老师), (语文, 李老师)},则S在Y(课程)上的投影为{数学, 语文}。
- R÷S的结果为{张三}(因张三的象集{数学, 语文}包含S的投影,而李四的象集{数学}不包含)。
-
广义投影(Generalized Projection)
- 定义:对投影的扩展,允许在投影列表中使用算术运算(+、-、×、÷)或函数,生成新的属性列。
- 示例:订单表(订单号,数量,单价),广义投影π₍订单号, 数量×单价₎(订单表),可直接得到“订单号,金额”的新关系。
-
外连接(Outer Join)
- 问题:普通连接(内连接)仅保留R和S中匹配的元组,不匹配的元组会被丢弃,导致信息缺失(如“没选课的学生”在学生表与选课表的连接中会被排除)。
- 解决:外连接保留不匹配的元组,用NULL填充缺失值,分为三种:
- 左外连接(R⋈ₚS):保留R中所有元组,S中不匹配的部分用NULL填充。
- 右外连接(R⋈ₚS):保留S中所有元组,R中不匹配的部分用NULL填充。
- 全外连接(R⋈ₚS):保留R和S中所有元组,不匹配的部分用NULL填充。
- 示例:学生表(学号,姓名)与选课表(学号,课程号)左外连接后,“没选课的学生”会被保留,课程号为NULL。
-
聚集函数(Aggregation Functions)
- 定义:对一组值(集合)进行计算,返回单一结果,用于统计分析。
- 常用函数:
- sum:求和(如sum(成绩)计算总分数)。
- avg:求平均值(如avg(年龄)计算平均年龄)。
- count:计数(count(*)统计所有元组,count(属性)统计非NULL值的个数)。
- min/max:求最小值/最大值(如min(成绩)、max(工资))。