第二章 关系模型导论
第二章 关系模型导论
2.1 关系数据库的结构
在逻辑层面上,关系数据库是被称为关系 (Relation) 的二维表的集合。每个关系代表一个实体集或一个关系集。
2.1.1 基本概念
| 术语 | 定义 |
|---|---|
| 关系 (Relation) | 二维表,代表一个实体集或关系集 |
| 元组 (Tuple) | 关系中的一行,代表一个实体或一个关系 |
| 属性 (Attribute) | 关系中的一列,具有名称 |
| 域 (Domain) | 每个属性允许的值的集合 |
| 原子性 (Atomic) | 属性值不可再分(如:属性值可以是一个账户号,但不能是一组账户号的集合) |
| null | 特殊值,是每个域的成员,表示未知或不存在 |
2.1.2 关系的数学定义
给定集合 D1,D2,…,DnD_1, D_2, \ldots, D_nD1,D2,…,Dn,一个关系 rrr 是笛卡尔积的子集:
r⊆D1×D2×⋯×Dnr \subseteq D_1 \times D_2 \times \cdots \times D_nr⊆D1×D2×⋯×Dn
因此,关系是一组 n 元组的集合,其中每个元组 (a1,a2,…,an)(a_1, a_2, \ldots, a_n)(a1,a2,…,an) 满足 ai∈Dia_i \in D_iai∈Di。
例:ID × name × salary → 关系 instructor 是该笛卡尔积的一个子集。
2.1.3 元组变量
元组变量是代表一个元组的变量,其域是某个特定关系的所有元组的集合。
例:t 是指向 instructor 中一个元组的变量:
t[ID]→ 12121t[name]→ Wut[dept_name]→ Financet[salary]→ 90000
2.1.4 关系是无序的
元组的顺序无关紧要——元组可以按任意顺序存储。
2.2 关系模式
2.2.1 关系模式与实例
- 关系模式:R=(A1,A2,…,An)R = (A_1, A_2, \ldots, A_n)R=(A1,A2,…,An),其中 AiA_iAi 为属性名
- 例:
instructor_schema = (ID, name, dept_name, salary)
- 例:
- 关系实例:r(R)r(R)r(R) 表示关系模式 R 上的一个关系
- 当前值(关系实例)由表指定
类比编程语言:模式 ≈ 类型声明,实例 ≈ 变量的值。
2.2.2 关系数据库
数据库由多个关系组成,企业信息被拆分为若干部分,每个关系存储一部分信息:
| 关系 | 存储信息 |
|---|---|
instructor |
教师信息 |
advisor |
哪位教师指导哪位学生 |
student |
学生信息 |
为什么不把所有信息放在一个关系中?
| 问题 | 说明 |
|---|---|
| 信息重复 | 若一位教师指导多名学生,教师信息会被重复存储 |
| 需要 null 值 | 要表示没有导师的学生,只能在教师相关列填 null |
规范化理论(第七章) 专门处理如何设计关系模式。
2.3 键
2.3.1 超键
设 K⊆RK \subseteq RK⊆R(R 为关系模式),K 是 R 的超键 (Superkey),当且仅当 K 的值足以唯一标识每个可能的关系 r(R)r(R)r(R) 中的一个元组。
"可能的关系"指企业建模中可能存在的关系。
例:{ID} 和 {ID, name} 都是 instructor 的超键。
2.3.2 候选键
超键 K 是候选键 (Candidate Key),当且仅当 K 是最小的——K 的任意真子集都不是超键。
例:{ID} 是 instructor 的候选键(它是超键且没有子集是超键),而 {ID, name} 不是候选键。
2.3.3 主键
主键 (Primary Key):被选作唯一标识元组的主要手段的候选键。
- 应选择其值从不或极少变化的属性
- 例:email 地址虽唯一但会变,不适合做主键
2.3.4 外键
关系 r1r_1r1 的某属性对应于另一个关系 r2r_2r2 的主键——该属性称为外键 (Foreign Key)。
| 术语 | 含义 |
|---|---|
| 引用关系 (Referencing Relation) | 包含外键的关系(r1r_1r1) |
| 被引用关系 (Referenced Relation) | 被外键引用的关系(r2r_2r2) |
例:depositor 中的 customer_name 和 account_number 分别引用 customer 和 account 的主键。
2.3.5 参照约束
被引用关系主键中出现的值才能出现在引用关系的外键中。
即:外键值集 ⊆ 主键值集。
2.4 模式图
模式图以图形方式展示数据库中各关系及其之间的外键依赖关系,是理解数据库整体结构的直观工具。
2.5 关系查询语言
| 分类 | 特点 | 代表 |
|---|---|---|
| 过程式 | 用户指定需要什么数据以及如何获取 | 关系代数 |
| 非过程式(声明式) | 用户只指定需要什么,不指定如何获取 | 元组关系演算、域关系演算 |
以上三种"纯"语言在计算能力上等价,但都不是图灵完备的。它们构成实际使用的查询语言(如 SQL)的底层基础。
本章重点讲解关系代数。
2.6 关系代数
关系代数是一种过程式语言,由一组以一个或两个关系为输入、产生一个新关系作为输出的运算组成。
2.6.1 六种基本运算
| 运算 | 符号 | 说明 |
|---|---|---|
| 选择 | σ\sigmaσ | 选出满足谓词的元组 |
| 投影 | π\piπ | 选出指定的列 |
| 并 | ∪\cup∪ | 两个关系的集合并 |
| 差 | −-− | 两个关系的集合差 |
| 笛卡尔积 | ×\times× | 两个关系元组的所有可能配对 |
| 重命名 | ρ\rhoρ | 给关系和属性重命名 |
2.6.2 选择运算
选出满足给定谓词的元组。对应 SQL 中 WHERE 子句。
σp(r)={t∣t∈r 且 p(t)}\sigma_p(r) = \{t \mid t \in r \text{ 且 } p(t)\}σp(r)={t∣t∈r 且 p(t)}
其中 p 是由以下项通过 ∧\land∧ (and)、∨\lor∨ (or)、¬\lnot¬ (not) 连接的命题演算公式,每项为:
<属性> op <属性> 或 <常量>\text{<属性> op <属性> 或 <常量>}<属性> op <属性> 或 <常量>
op 为:=、≠、>、≥、<、≤
-- 例:查找年龄小于 20 的所有学生
σ Sage < 20 (Student)
2.6.3 投影运算
选出指定的列——一元运算,从关系中擦除未列出的列。对应 SQL 中 SELECT 子句。
πA1,A2,…,Ak(r)\pi_{A_1, A_2, \ldots, A_k}(r)πA1,A2,…,Ak(r)
结果中重复行被去除,因为关系是集合。
-- 例:查找所有学生的姓名和院系
π Sname, Sdept (Student)
-- 或使用列序号:π 2,5 (Student)
2.6.4 并运算
集合的并运算。
r∪s={t∣t∈r 或 t∈s}r \cup s = \{t \mid t \in r \text{ 或 } t \in s\}r∪s={t∣t∈r 或 t∈s}
前提条件:
- rrr 和 sss 必须具有相同的元数(相同属性数)
- 属性域必须兼容(如:r 的第 2 列与 s 的第 2 列处理相同类型的值)
-- 例:查找 2017 秋或 2018 春开课的所有课程
π course_id (σ semester="Fall" ∧ year=2017 (section))
∪
π course_id (σ semester="Spring" ∧ year=2018 (section))
2.6.5 集合差运算
集合的差运算。
r−s={t∣t∈r 且 t∉s}r - s = \{t \mid t \in r \text{ 且 } t \notin s\}r−s={t∣t∈r 且 t∈/s}
同样要求 r 和 s 兼容。
-- 例:查找 2017 秋开课但 2018 春未开课的课程
π course_id (σ semester="Fall" ∧ year=2017 (section))
−
π course_id (σ semester="Spring" ∧ year=2018 (section))
2.6.6 集合交运算
集合的交运算。可由差运算推导:r∩s=r−(r−s)r \cap s = r - (r - s)r∩s=r−(r−s)
r∩s={t∣t∈r 且 t∈s}r \cap s = \{t \mid t \in r \text{ 且 } t \in s\}r∩s={t∣t∈r 且 t∈s}
-- 例:查找 2017 秋和 2018 春都开课的课程
π course_id (σ semester="Fall" ∧ year=2017 (section))
∩
π course_id (σ semester="Spring" ∧ year=2018 (section))
2.6.7 笛卡尔积运算
将一个关系的每个元组与另一个关系的每个元组配对。
r×s={t q∣t∈r 且 q∈s}r \times s = \{t\ q \mid t \in r \text{ 且 } q \in s\}r×s={t q∣t∈r 且 q∈s}
- 假设 r(R)r(R)r(R) 和 s(S)s(S)s(S) 的属性不相交(R∩S=∅R \cap S = \emptysetR∩S=∅)
- 若属性名重叠,必须使用重命名
直接使用笛卡尔积意义不大,需结合选择运算才有用。
示例: instructor × teaches
- 结果包含两个关系中每个可能的元组对
- 由于
ID同时出现在两个关系中,用关系名前缀区分:instructor.ID和teaches.ID
2.6.8 关系运算的复合
关系代数运算的结果也是关系,因此可以将多个运算复合成一个关系代数表达式。
-- 例:查找 Physics 系所有教师的名字
π name (σ dept_name="Physics" (instructor))
2.6.9 连接运算
笛卡尔积 instructor × teaches 会将每个 instructor 元组与每个 teaches 元组关联——其中大多无实际意义。
连接 = 笛卡尔积 + 选择:只保留与目标相关的元组对。
-- 获取每位教师及其所教课程的信息
σ instructor.ID = teaches.ID (instructor × teaches)
等值连接:连接谓词为等值比较的连接。
2.6.10 重命名运算
ρx(E)\rho_x(E)ρx(E)
ρx(A1,A2,…,An)(E)\rho_{x(A_1, A_2, \ldots, A_n)}(E)ρx(A1,A2,…,An)(E)
| 形式 | 含义 |
|---|---|
| ρx(E)\rho_x(E)ρx(E) | 将表达式 E 的结果命名为 x |
| ρx(A1,…,An)(E)\rho_{x(A_1,\ldots,A_n)}(E)ρx(A1,…,An)(E) | 将结果命名为 x 并将属性重命名为 A1,…,AnA_1, \ldots, A_nA1,…,An |
用途:
- 对关系代数表达式的结果命名以便引用
- 允许用多个名称引用同一关系(如自连接场景)
-- 例:查找与 Smith 住在同一城市的所有客户
-- 先将名为 "Smith" 的客户信息选出并重命名为 smith_info
-- 再做笛卡尔积 + 选择 + 投影
π customer.customer_name (
σ customer.customer_city = smith_info.customer_city (
customer × ρ smith_info (σ customer_name="Smith" (customer))
)
)
2.6.11 赋值运算
用 ←\leftarrow← 将关系代数表达式的部分结果赋给临时关系变量,便于编写顺序程序式的查询。
-- 例:查找 Physics 系和 Music 系的教师
Physics ← σ dept_name="Physics" (instructor)
Music ← σ dept_name="Music" (instructor)
Physics ∪ Music
2.6.12 等价查询
同一个查询可以有多种关系代数写法——形式不同但结果等价。
-- 查询 1:一步完成
σ dept_name="Physics" ∧ salary > 90000 (instructor)
-- 查询 2:分两步选择
σ dept_name="Physics" (σ salary > 90000 (instructor))
-- 两者在任何数据库上给出相同结果——它们是等价的
本章重点:理解关系模型的数学基础(笛卡尔积定义)、关系模式与实例的区别、超级键/候选键/主键/外键的层级关系与参照约束、以及关系代数的六种基本运算(σ,π,∪,−,×,ρ\sigma, \pi, \cup, -, \times, \rhoσ,π,∪,−,×,ρ)及其复合使用。关系代数是 SQL 的理论基础——SELECT 对应投影、WHERE 对应选择、FROM+JOIN 对应笛卡尔积+选择。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)