Lecture 5:关系数据理论
Chinese-language Computer Science 408 note: Lecture 5:关系数据理论. Original source available where applicable.
On this page
This note is currently available in Chinese. The original wording, formulas and diagrams are preserved to avoid an unverified technical translation.
描述:本节从冗余与更新异常出发,整理函数依赖、平凡/非平凡依赖、完全/部分依赖和传递依赖,并依次说明 1NF、2NF、3NF、BCNF 的判定、分解与 SQL 示例。
5.1 不良关系模式的问题
课件把学生、系、系主任、课程和成绩放在一个关系中:
$$ \operatorname{Teaching}( \text{学号},\text{姓名},\text{年龄}, \text{系名},\text{系主任}, \text{课程名},\text{成绩} ). $$
同一学生选多门课时,姓名、年龄、系名和系主任会重复出现。
5.1.1 数据冗余
同一事实存储多次,例如每条选课记录都重复学生和院系信息。
5.1.2 更新异常
若某系主任更换,必须修改该系所有相关元组;漏改一行就产生矛盾。
5.1.3 插入异常
如果某系暂时没有学生或课程,可能无法单独插入系和系主任信息。
5.1.4 删除异常
删除某学生最后一条选课记录时,可能同时丢失学生、系或系主任事实。
这些异常的根源不是“表太宽”本身,而是多个不同语义的函数依赖被混放在同一关系模式中。
5.2 函数依赖
设关系模式:
$$ R(U), $$
$X,Y\subseteq U$。若对 $R$ 的任何合法关系实例,任意两个元组在 $X$ 上取值相同,就必然在 $Y$ 上取值相同,则称 $X$ 函数决定 $Y$:
$$ X\rightarrow Y. $$
也称 $Y$ 函数依赖于 $X$。
例如:
$$ \text{Sno}\rightarrow\text{Sname}, $$
$$ \text{Sno}\rightarrow\text{Sdept}. $$
含义是同一学号不能对应两个不同姓名或院系。
WARNING 函数依赖是关系模式语义上的约束,不能只根据当前少量样本“碰巧没有重复”就断定成立。
5.3 平凡与非平凡函数依赖
5.3.1 平凡函数依赖
若:
$$ Y\subseteq X, $$
则:
$$ X\rightarrow Y $$
是平凡函数依赖,总是成立。
例如:
$$ {\text{StudentID},\text{Name}} \rightarrow {\text{Name}}. $$
5.3.2 非平凡函数依赖
若:
$$ Y\nsubseteq X, $$
则 $X\rightarrow Y$ 是非平凡函数依赖。
若还有:
$$ X\cap Y=\varnothing, $$
则称完全非平凡依赖。
规范化判定主要关注非平凡函数依赖。
5.4 完全与部分函数依赖
5.4.1 完全函数依赖
若 $X\rightarrow Y$,且对 $X$ 的任何真子集 $X'$ 都有:
$$ X'\nrightarrow Y, $$
则 $Y$ 完全函数依赖于 $X$,记作:
$$ X\xrightarrow{F}Y. $$
5.4.2 部分函数依赖
若 $X\rightarrow Y$,但存在真子集 $X'\subset X$ 使:
$$ X'\rightarrow Y, $$
则 $Y$ 部分函数依赖于 $X$,记作:
$$ X\xrightarrow{P}Y. $$
例如选课关系的候选码为:
$$ (\text{StudentID},\text{CourseID}), $$
而:
$$ \text{StudentID}\rightarrow\text{StudentName}, $$
所以 StudentName 对复合码是部分依赖。
单属性候选码没有非空真子集,因此不会产生针对该码的部分依赖。
5.5 传递函数依赖
若:
$$ X\rightarrow Y, $$
$$ Y\rightarrow Z, $$
且 $Y\nrightarrow X$,$Z\nsubseteq Y$,则称 $Z$ 对 $X$ 传递函数依赖:
$$ X\xrightarrow{T}Z. $$
课件例子:
$$ \text{学号}\rightarrow\text{系名}, $$
$$ \text{系名}\rightarrow\text{系主任名字}, $$
所以:
$$ \text{学号}\xrightarrow{T}\text{系主任名字}. $$
传递依赖会让系主任信息在每个学生元组中重复。
5.6 候选码与属性闭包
给定函数依赖集 $F$,属性集 $X$ 关于 $F$ 的闭包 $X_F^+$ 是由 $X$ 能函数决定的全部属性。
若:
$$ X_F^+=U, $$
则 $X$ 是超码;若 $X$ 还没有能决定 $U$ 的真子集,则 $X$ 是候选码。
闭包计算:
- 初始化 $X^+=X$。
- 若存在 $Y\rightarrow Z$ 且 $Y\subseteq X^+$,把 $Z$ 加入 $X^+$。
- 重复直到不再增加属性。
范式判定前必须先确认候选码和主属性,否则容易误判 2NF、3NF、BCNF。
5.7 范式与规范化
范式(Normal Form)是评价关系模式规范化程度的理论标准。
常见层次:
$$ \text{1NF} \supset \text{2NF} \supset \text{3NF} \supset \text{BCNF}. $$
更高阶还有 4NF、5NF,分别处理多值依赖和连接依赖。
规范化是把低级范式的关系模式分解为更高级范式的过程,目标是减少冗余和更新异常。
NOTE 范式越高通常冗余越少,但查询可能需要更多连接,不能简单说所有操作复杂度都必然降低。设计时还要权衡无损连接、依赖保持和性能。
5.8 第一范式 1NF
5.8.1 定义
若关系模式的每个属性在当前关系模型中都取原子值,即每个分量是定义域中的单一值,则属于第一范式。
直观要求:
- 一个单元格不能放可变数量的列表或重复组。
- 每一列在既定语义下取单一值。
1NF 是关系模型的基本要求。
5.8.2 出生日期图的准确解释
课件把出生日期分成“年、月、日”来说明可分性。
如果一个单元格内部存放结构化的多个独立字段,且系统要把它们当重复组处理,可能违反 1NF。
但现代数据库中的单个 DATE 值属于一个原子定义域,即使逻辑上能提取年、月、日,也不因此违反 1NF。
WARNING · 课件图示纠错 “出生日期能拆成年月日,所以一定不属于 1NF”过于机械。原子性相对于关系模式选定的定义域和业务语义;标准
DATE列通常视为原子值。
5.9 第二范式 2NF
5.9.1 定义
关系模式 $R$ 属于 2NF,当且仅当:
- $R\in\text{1NF}$;
- 每个非主属性都完全函数依赖于每一个候选码,不存在对候选码真子集的部分依赖。
口诀:
2NF:消除非主属性对候选码的部分依赖
5.9.2 推论
若所有候选码都是单属性,则不会存在对候选码的部分依赖,因此满足 1NF 的该关系必然满足 2NF。
5.9.3 课件选课例子
原关系:
CREATE TABLE StudentCourses (
StudentID INT,
CourseID INT,
StudentName VARCHAR(50),
PRIMARY KEY (StudentID, CourseID)
);
函数依赖:
$$ (\text{StudentID},\text{CourseID}) \rightarrow\text{StudentName}, $$
同时:
$$ \text{StudentID}\rightarrow\text{StudentName}. $$
所以 StudentName 只依赖复合码的一部分,不符合 2NF。
分解为:
CREATE TABLE Students (
StudentID INT PRIMARY KEY,
StudentName VARCHAR(50)
);
CREATE TABLE StudentCourses (
StudentID INT,
CourseID INT,
PRIMARY KEY (StudentID, CourseID),
FOREIGN KEY (StudentID)
REFERENCES Students(StudentID)
);
学生姓名只存一份,选课关系只保留与整个复合码有关的事实。
5.10 第三范式 3NF
5.10.1 直观定义
关系满足 2NF,并且非主属性不传递依赖于候选码,则属于 3NF。
口诀:
3NF:消除非主属性对候选码的传递依赖
5.10.2 正式判定
对函数依赖集 $F^+$ 中每个非平凡依赖:
$$ X\rightarrow A, $$
至少满足一项:
- $X$ 是超码;
- $A$ 是主属性。
第二项是 3NF 与 BCNF 的关键差别。
5.10.3 课件班级例子
原关系:
CREATE TABLE Students (
StudentID INT PRIMARY KEY,
Name VARCHAR(50),
ClassID INT,
ClassName VARCHAR(50)
);
存在:
$$ \text{StudentID}\rightarrow\text{ClassID}, $$
$$ \text{ClassID}\rightarrow\text{ClassName}. $$
所以 ClassName 传递依赖于 StudentID,不符合 3NF。
分解为:
CREATE TABLE Classes (
ClassID INT PRIMARY KEY,
ClassName VARCHAR(50)
);
CREATE TABLE Students (
StudentID INT PRIMARY KEY,
Name VARCHAR(50),
ClassID INT,
FOREIGN KEY (ClassID)
REFERENCES Classes(ClassID)
);
5.10.4 二属性关系
对只有两个属性 $A,B$ 的关系模式,若非平凡函数依赖的决定因素非空,例如 $A\to B$,则 $A$ 连同其平凡决定的自身可决定全部属性,所以决定因素是超码,通常满足 BCNF,自然也满足 3NF。这个常用结论隐含了“忽略空决定因素”的教材口径;若允许 $\varnothing\to A$ 且 $\varnothing$ 不能决定 $B$,则 $\varnothing$ 不是超码,二属性关系仍可违反 BCNF。
5.11 BCNF
5.11.1 定义
关系模式 $R$ 属于 BCNF,当且仅当对 $F^+$ 中每个非平凡函数依赖:
$$ X\rightarrow Y, $$
$X$ 都是超码。
口诀:
BCNF:每个非平凡函数依赖的决定因素都是超码
BCNF 蕴含 3NF,但 3NF 不一定蕴含 BCNF。
5.11.2 课件课程-教师例子
原关系:
CREATE TABLE StudentCourses (
StudentID INT,
CourseID INT,
TeacherID INT,
PRIMARY KEY (StudentID, CourseID)
);
业务规定每门课程只有一名教师:
$$ \text{CourseID}\rightarrow\text{TeacherID}. $$
CourseID 不是超码,所以违反 BCNF。
可分解为:
CREATE TABLE Courses (
CourseID INT PRIMARY KEY,
TeacherID INT
);
CREATE TABLE StudentCourses (
StudentID INT,
CourseID INT,
PRIMARY KEY (StudentID, CourseID),
FOREIGN KEY (CourseID)
REFERENCES Courses(CourseID)
);
WARNING · 例子口径纠错 在该模式中
TeacherID是非主属性,CourseID又不是超码,因此CourseID→TeacherID同时违反 3NF。它能说明 BCNF 的决定因素要求,但不是“满足 3NF、仅违反 BCNF”的严格反例。
5.11.3 3NF 但不满足 BCNF 的严格例子
设:
$$ R(S,C,T), $$
函数依赖:
$$ SC\rightarrow T, $$
$$ T\rightarrow C. $$
候选码为:
$$ SC, ST. $$
在 $T\rightarrow C$ 中:
- $T$ 不是超码,所以违反 BCNF。
- $C$ 属于候选码 $SC$,是主属性,所以满足 3NF 的例外条件。
因此该关系满足 3NF,但不满足 BCNF。
5.12 范式包含与快速判定
| 范式 | 核心条件 | 消除的问题 |
|---|---|---|
| 1NF | 属性取原子值 | 重复组、非原子分量 |
| 2NF | 非主属性完全依赖候选码 | 部分依赖 |
| 3NF | 非平凡 $X\to A$ 中,$X$ 为超码或 $A$ 为主属性 | 非主属性传递依赖 |
| BCNF | 每个非平凡依赖左部都是超码 | 决定因素不是码造成的冗余 |
判定步骤:
- 写出关系模式和函数依赖集。
- 用属性闭包求全部候选码。
- 标出主属性与非主属性。
- 检查属性是否原子,判断 1NF。
- 检查非主属性是否部分依赖候选码,判断 2NF。
- 用 3NF 正式条件检查每个非平凡依赖。
- 检查每个决定因素是否都是超码,判断 BCNF。
5.13 分解的质量要求
提高范式时不能只追求“拆表”,还要考虑:
5.13.1 无损连接
分解后自然连接应能恢复原关系,不能产生伪元组或丢失合法信息。
二元分解 $R\to R_1,R_2$ 对函数依赖集 $F$ 无损的常用判据是:
$$ (R_1\cap R_2)\rightarrow R_1 $$
或:
$$ (R_1\cap R_2)\rightarrow R_2 $$
能由 $F^+$ 推出。
5.13.2 依赖保持
原函数依赖应尽量能在各子关系内部检查,而不必每次连接多个关系。
3NF 综合算法通常能兼顾无损连接与依赖保持;BCNF 分解保证无损,但可能不能保持全部依赖。
5.14 易错点
- 函数依赖是模式语义约束,不是从当前样本偶然现象推断。
- $Y\subseteq X$ 时 $X\to Y$ 是平凡依赖。
- 完全依赖要求左部任何真子集都不能决定右部;存在能决定右部的真子集就是部分依赖。
- 2NF 检查的是每个非主属性对每个候选码,不是只看已选主键。
- 单属性候选码的 1NF 关系不会有部分依赖,因此满足 2NF。
- 3NF 的正式条件允许右部为主属性;BCNF 不允许这一例外。
- BCNF 要求每个非平凡依赖的左部为超码,不是“右部为超码”。
- 标准
DATE值通常是原子定义域,不能因可提取年月日就直接判为非 1NF。 - 课件的课程-教师关系同时违反 3NF 与 BCNF,不是两者差异的严格反例。
- 范式提高减少冗余,但可能增加查询连接,不能忽略无损连接和依赖保持。
相关知识
- 科目导航:复试常考科目导航
- 阅读顺序:上一篇:数据库完整性 · 下一篇:数据库设计
- 关联专题:数据库逻辑设计
5.15 本节复盘
- 不良关系模式会产生冗余、插入异常、删除异常和更新异常,根源是依赖混杂。
- $X\to Y$ 表示相同 $X$ 值必然对应相同 $Y$ 值。
- 平凡依赖的右部包含在左部;部分依赖、传递依赖分别导致 2NF、3NF 问题。
- 属性闭包用于判断超码和候选码,是范式判定的前置工具。
- 1NF 要求属性相对于定义域取原子值。
- 2NF 消除非主属性对候选码的部分依赖。
- 3NF 要求每个非平凡依赖左部为超码,或右部为主属性。
- BCNF 更严格,要求每个非平凡依赖的左部都是超码。
- 规范化分解还必须关注无损连接和依赖保持,不能机械拆表。