← Back to Learning Notes

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$ 是候选码。

闭包计算:

  1. 初始化 $X^+=X$。
  2. 若存在 $Y\rightarrow Z$ 且 $Y\subseteq X^+$,把 $Z$ 加入 $X^+$。
  3. 重复直到不再增加属性。

范式判定前必须先确认候选码和主属性,否则容易误判 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,当且仅当:

  1. $R\in\text{1NF}$;
  2. 每个非主属性都完全函数依赖于每一个候选码,不存在对候选码真子集的部分依赖。

口诀:

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, $$

至少满足一项:

  1. $X$ 是超码;
  2. $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 每个非平凡依赖左部都是超码 决定因素不是码造成的冗余

判定步骤:

  1. 写出关系模式和函数依赖集。
  2. 用属性闭包求全部候选码。
  3. 标出主属性与非主属性。
  4. 检查属性是否原子,判断 1NF。
  5. 检查非主属性是否部分依赖候选码,判断 2NF。
  6. 用 3NF 正式条件检查每个非平凡依赖。
  7. 检查每个决定因素是否都是超码,判断 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 更严格,要求每个非平凡依赖的左部都是超码。
  • 规范化分解还必须关注无损连接和依赖保持,不能机械拆表。