










假设我们有一个表格存储学生成绩信息:
学生成绩表
| 学号 (SNo) | 课程号 (CNo) | 分数 (Score) | 姓名 (Name) | 班级 (Class) |
|---|
前提:X——>Y(即X决定Y)
依据:依赖关系中Y是否为X的子集。即基于属性集的包含关系(Y是否属于X)
平凡依赖指的是属性集中的某个属性依赖于自身。不需要从其他属性获得信息。
例子:
非平凡依赖是指如果 X → Y 成立并且 Y 不属于 X,这称为非平凡依赖。
例子:
依据:依赖关系中X的真子集是否决定Y,或是否通过中间属性间接决定。 即 基于依赖的完整性(是否需全部属性)或传递性(是否通过中间属性)
完全函数依赖是指 Y 对 X 是完全依赖的,但对 X 的任何真子集都不依赖,即去掉任何一个 X 的成分,依赖关系不再成立。
例子:
部分函数依赖指的是在一个复合主键中,如果有一个非主属性依赖于主键的一部分,而不是整个主键。
假设学生成绩表的主键是由“学号 (SNo)”和“课程号 (CNo)”组合而成,这样能唯一标识一条记录。
然而,“姓名 (Name)”和“班级 (Class)”只依赖于“学号 (SNo)”而非整个主键,因为一个学生会有多个课程。因此,这里有部分函数依赖:
传递函数依赖是指如果存在 X → Y 和 Y → Z,那么就有 X → Z。通常在属性集合中隐含信息传递。
例子:
班级信息表
| 班级 (Class) | 班长 (Leader) |
|--------------|---------------|
在这种情况下,学生成绩表中的班级对班长存在传递函数依赖:{SNo} → {Class} 和 {Class} → {Leader},因此 {SNo} → {Leader} 是传递依赖。
这些不同类型的依赖关系帮助我们识别数据库设计中的冗余、异常,并指导我们进行范式化处理。
不会发生插入异常、删除异常、更新异常,数据冗余应尽可能少。
https://fangkaipeng.com/?p=921
例:关系模式R中 (学生的学号(Sno)、所在系(Sdept)系主任姓名(Mname)、课程名(Cname)、成绩(Grade))
上述的关系模式不是一个好的关系模式。这是由存在于模式中的某些数据依赖引起的,可以通过分解关系模式来消除其中不合适的数据依赖。
第一:属性 不可再分
(消除多值属性与重复字段)
2NF:满足1NF,且 非主属性 完全依赖 主属性,而不是部分依赖(消除冗余更新异常)
将原关系 R 分解为以下两个表:
学生-系表(Student_Dept):
属性:Sno(学号)、Sdept(系)、Mname(系主任)
候选键:Sno(完全函数依赖)
依赖关系:Sno → Sdept → Mname。
通过分解,原关系中的冗余数据和部分依赖被消除,满足第二范式要求
第三:满足第二,且消除传递依赖
(消除传递依赖导致的数据冗余)
BCNF:满足3NF,且对于每一个非平凡的函数依赖 X -> Y,X 必须是一个候选键,而不仅仅涉及主键(或候选键)的一部分。
假设我们有一个表 Enrollments:候选键(CourseID, ProfessorID),但是有依赖 CourseID -> ProfessorID,违反BCNF
| CourseID | ProfessorID | StudentID | ProfessorName |
|---|---|---|---|
| C001 | P001 | S001 | Dr. Smith |
| C002 | P002 | S002 | Dr. Johnson |
假设 CourseID 是唯一的课程标识,所以 CourseID -> ProfessorID 是一个函数依赖。在这种情况下,ProfessorName 对 ProfessorID 和 CourseID 的依赖不是符合BCNF的,因为 ProfessorID 本身应该是一个候选键。
为使表进入BCNF,我们需要分解表:
ProfessorDetails 表:| ProfessorID | ProfessorName |
|---|---|
| P001 | Dr. Smith |
| P002 | Dr. Johnson |
Enrollments 表:| CourseID | ProfessorID | StudentID |
|---|---|---|
| C001 | P001 | S001 |
| C002 | P002 | S002 |
在这里,通过分解 we 能够消除 ProfessorName 的传递依赖,因为它直接从 ProfessorID 派生,而 ProfessorID 是一个候选键。
通过这些示例,我们可以看到,2NF 主要关注消除部分依赖,而 BCNF 关注任何情况下的函数依赖,确保候选键的充分利用。
好的,让我们来看看一个符合第二范式 (2NF) 但是不符合 Boyce-Codd 范式 (BCNF) 的例子。
示例表:Assignments
假设我们有一个表 Assignments,其中:
(StudentID, AssignmentID)。假设表结构如下:
| StudentID | AssignmentID | CourseID | CourseInstructor |
|---|---|---|---|
| S001 | A001 | C001 | Dr. Smith |
| S002 | A002 | C002 | Dr. Johnson |
| S001 | A003 | C001 | Dr. Smith |
| S002 | A004 | C003 | Dr. Williams |
依赖关系:
(StudentID, AssignmentID)。CourseID 和 CourseInstructor 是对 (StudentID, AssignmentID) 的完全依赖,因为它们由两个属性决定。CourseID -> CourseInstructor 是一个非主属性到非主属性的依赖。2NF 分析
该表已满足 1NF,因为所有属性均为原子值。
通过查看 (StudentID, AssignmentID) 的组合,我们看不到部分依赖。
因此,该表符合 2NF,因为所有非主属性都对整个主键而不是部分主键完全依赖。
BCNF 分析
BCNF 要求每个函数依赖具有候选键。
CourseID -> CourseInstructor 是一个非平凡的函数依赖,但 CourseID 不是候选键。CourseID 不是候选键。分解到BCNF
为了使表达到 BCNF,我们可以通过将表分解为两个表:
Courses 表:| CourseID | CourseInstructor |
|---|---|
| C001 | Dr. Smith |
| C002 | Dr. Johnson |
| C003 | Dr. Williams |
Assignments 表:| StudentID | AssignmentID | CourseID |
|---|---|---|
| S001 | A001 | C001 |
| S002 | A002 | C002 |
| S001 | A003 | C001 |
| S002 | A004 | C003 |
这样,CourseInstructor 直接依赖于候选键 CourseID,符合 BCNF 要求。在这种情况下,我们消除了非主键间的依赖关系,并确保所有非平凡的函数依赖都有一个候选键。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。