数据库设计三范式(NF)之第三范式极简说明

一句话核心思想

第三范式就是:消除“间接依赖”,表中不能有“子关系”。

更专业一点说:在满足第二范式的基础上,确保表中的每一列都直接依赖于主键,而不能依赖于其他非主键列(即不能存在传递依赖)。


用一个生动的例子来解释

假设我们有一张 学生表,记录学生、他们的学院以及学院的详细信息。

学号 (主键)姓名所在学院学院院长学院地点
2023001 张三 计算机学院 李教授 科技楼A座
2023002 李四 计算机学院 李教授 科技楼A座
2023003 王五 外国语学院 张教授 人文楼B座

这张表有什么问题?(它违反第三范式)

  1. 冗余重复:

    • 张三是计算机学院的,李四也是。那么“计算机学院”的院长和地点信息就被重复存储了多次。如果一个学院有几千个学生,这个信息就会被重复几千次!

  2. 更新异常:

    • 如果计算机学院换院长了,新任院长是“王教授”。我们必须找到所有所在学院 = 计算机学院的记录,一条一条地去修改学院院长字段。万一漏改了一行,就会导致数据不一致(有的记录是李教授,有的记录是王教授)。

  3. 插入异常:

    • 学校新成立了一个“法学院”,已经任命了院长“赵教授”,地点在“社科楼C座”。但是,如果还没有学生被录入这个学院,我们就无法把这个新学院的信息插入到这张表里。因为学号主键不能为空。

  4. 删除异常:

    • 如果学生“李四”毕业了,我们从表中删除了他的记录。假如他恰好是计算机学院的最后一个学生,那么删除这条记录的同时,我们也会意外地丢失“计算机学院”的院长和地点信息。

为什么会这样?

因为这张表里存在“间接依赖”,也叫“传递依赖”。我们来分析一下依赖关系:

  • 学号 (主键) -> 决定了姓名所在学院。 ✅ (这没问题)

  • 学号 (主键) -> 所在学院 -> 决定了学院院长学院地点。 ❌ (问题在这里!)

学院院长学院地点并不是直接由学号决定的,而是由所在学院这个非主键字段决定的。学号决定了所在学院所在学院又决定了学院院长,这就形成了一个传递链。

这种“一个非主键字段决定了其他非主键字段”的情况,就是违反第三范式的根源。


如何改造?(使其符合第三范式)

核心操作:继续拆表!把“子关系”独立出去。

我们把上面那张表拆成两张表:

1. 学生表 (核心信息:学生和学院的从属关系)

学号 (主键)姓名所在学院 (外键)
2023001 张三 计算机学院
2023002 李四 计算机学院
2023003 王五 外国语学院

2. 学院表 (专门管理学院的详细信息)

学院名称 (主键)学院院长学院地点
计算机学院 李教授 科技楼A座
外国语学院 张教授 人文楼B座
法学院 赵教授 社科楼C座 (新学院可以独立添加了!)

改造后的好处:

  • 数据冗余彻底消除:每个学院的信息(院长、地点)只存储一次,而不是随着学生数量重复存储。

  • 避免更新异常:计算机学院换院长,只需在学院表里修改一条记录即可。

  • 避免插入异常:新成立的“法学院”可以直接添加到学院表,完全不受是否有学生的影响。

  • 避免删除异常:即使计算机学院的所有学生都毕业了,其信息依然安全地保存在学院表中。


总结:如何判断和满足第三范式?

  1. 第一步:确保你的表已经满足了第二范式。

  2. 第二步:检查表中的每一个非主键字段,问自己两个问题:

    a. “这个字段是直接依赖于主键吗?”
    b. “这个字段会不会依赖于另一个非主键字段?”

  3. 第三步:如果发现存在这种“传递依赖”(即字段A依赖于主键,但字段B又依赖于字段A),就把这些间接依赖的字段(B)拆出去,建立一张新表,让决定它们的那个字段(A)成为新表的主键。

一个简单的记忆口诀

  • 第一范式(1NF):列不可再分。(保证原子性)

  • 第二范式(2NF):消除部分依赖。(非主键字段必须完全依赖整个主键)

  • 第三范式(3NF):消除传递依赖。(非主键字段之间不能有依赖关系)

最终记住那个简单的比喻:

  • 违反2NF:像一个员工同时向两个部门经理汇报工作,职责不清。

  • 违反3NF:像在员工表里不仅记录了员工的部门,还记录了部门的预算、部门的规章制度等。这些信息本应属于部门表,而不是员工表。

posted @ 2025-08-21 09:41  爆炸球  阅读(26)  评论(0)    收藏  举报