数据库设计三范式(NF)之BC范式极简说明
BCNF被认为是修正的第三范式,比3NF的要求更加严格。当关系模型满足3NF但仍可能存在一些异常时,就需要用到BCNF。
一句话核心思想
BC范式就是:主键和非主键之间,不允许存在任何“决定”关系。
更专业地说:在第三范式的基础上,确保表中的每一个决定因素(Determinant)都必须是候选键(Candidate Key)。
关键概念解析
-
决定因素(Determinant):如果一个字段(或字段组)X的值可以唯一确定另一个字段Y的值,那么X就是Y的决定因素。记作 X → Y。
-
例如:
学号→姓名,课程号→课程名。这里的学号和课程号都是决定因素。
-
-
候选键(Candidate Key):能够唯一标识表中一条记录的最小字段集合。一个表可以有多个候选键。
-
例如:在
学生表(学号, 身份证号, 姓名)中,学号和身份证号都是候选键。
-
-
主键(Primary Key):从候选键中选出来的一个,作为表的主要标识。
BCNF的核心要求是:如果一个X能决定Y(X → Y),那么X必须是一个候选键(超键)。
用一个经典例子来解释(学生-导师-课程)
假设我们有一个大学的规定:
-
一位学生(S)可以选择多位导师(T)来指导。
-
一位导师只属于一个学院(D)。
-
一位导师可以指导多位学生。
-
一个学院有多位导师。
我们设计这样一张表:
| 学生 (Student) | 导师 (Tutor) | 学院 (Department) |
|---|---|---|
| 张三 | 王教授 | 计算机学院 |
| 李四 | 王教授 | 计算机学院 |
| 张三 | 刘教授 | 数学学院 |
| 王五 | 刘教授 | 数学学院 |
分析这张表:
-
找出函数依赖(FD):
-
导师→学院:一位导师只属于一个学院。(例如,王教授一定在计算机学院) -
(学生, 导师)→学院:我知道学生和导师,自然就知道学院。 -
(学生, 学院)→导师? 不一定! 一个学生可以在一个学院选择多位不同的导师(比如张三既选了计算机学院的王教授,又选了计算机学院的另一位教授)。所以这个依赖不成立。
-
-
找出候选键:
-
由于
(学生, 学院)不能唯一确定导师,所以它不是候选键。 -
只有
(学生, 导师)可以唯一确定一条记录(一个学生选一个导师的组合是唯一的),所以(学生, 导师)是唯一的候选键,也就是主键。
-
-
检查是否满足3NF:
-
第三范式要求:非主属性必须直接依赖于主键,不能存在传递依赖。
-
学院依赖于主键(学生,导师)吗? 是的,因为我知道学生和导师,就能确定学院。✅ -
学院也依赖于导师(导师→学院)。而导师是主键的一部分(是一个非主属性?这里有点绕)。 -
实际上,因为
导师是主键的一部分,所以不存在非主属性对非主属性的传递依赖。因此,这张表是满足第三范式(3NF)的!
-
-
但它仍然有问题(违反BCNF):
-
问题所在:我们有一个决定因素
导师→学院,但导师本身不是一个候选键(单独的导师不能唯一标识一条记录,因为一个导师可以教多个学生,会出现在多行)。 -
这就违反了BCNF的原则:
导师是一个决定因素,但它不是候选键。
-
会引发什么异常?
-
插入异常:学校新来了一位赵教授,在物理学院,但还没有任何学生选他做导师。我们就无法将
(赵教授, 物理学院)这个信息插入表中,因为学生作为主键的一部分不能为空。 -
更新异常:如果王教授从计算机学院转到了软件学院,我们必须修改所有
导师=王教授的记录(有多条),而不能只修改一次。 -
删除异常:如果学生李四毕业了,我们删除他的记录。如果王教授只有李四这一个学生,那么删除李四记录的同时,我们也丢失了“王教授在计算机学院”这个信息。
如何改造?(使其符合BCNF)
核心操作:将违反BCNF的函数依赖分离到单独的表中。
那个违反BCNF的函数依赖是:导师 → 学院。我们需要把它拆出去。
拆分成两张表:
1. 导师-学院表 (核心:存储导师属于哪个学院)
| 导师 (主键) | 学院 | |
|---|---|---|
| 王教授 | 计算机学院 | |
| 刘教授 | 数学学院 | |
| 赵教授 | 物理学院 | (新导师可以独立添加了!) |
2. 学生-导师表 (核心:存储学生选择了哪位导师)
| 学生 | 导师 |
|---|---|
| 张三 | 王教授 |
| 李四 | 王教授 |
| 张三 | 刘教授 |
| 王五 | 刘教授 |
改造后的好处:
-
符合BCNF:
-
在
导师-学院表中,主键是导师,它决定了学院。决定因素就是候选键。 -
在
学生-导师表中,主键是(学生, 导师),没有其他函数依赖。也符合BCNF。
-
-
所有异常被消除:
-
可以单独添加新导师的信息。
-
修改导师的学院,只需在
导师-学院表中修改一次。 -
删除学生记录,不会影响导师信息的完整性。
-
总结:BCNF与3NF的关系
-
BCNF比3NF更严格。所有满足BCNF的关系一定满足3NF,但满足3NF的关系不一定满足BCNF。
-
3NF允许一种“宽松”:如果被决定的属性Y是主键的一部分(就像上面例子中的
导师),即使存在决定因素X不是候选键,也允许。BCNF不允许这种宽松,它要求任何决定因素都必须是候选键。 -
在实际数据库设计中,BCNF是更理想的标准,因为它能解决3NF无法解决的异常情况。大部分情况下,达到BCNF就认为数据库结构已经非常规范了。
简单记忆:
BCNF是3NF的加强版,它堵上了3NF的一个小漏洞,要求所有“能决定别人”的字段,自己必须是“老大”(候选键)。

浙公网安备 33010602011771号