一文搞懂数据库设计范式:1NF、2NF、3NF 和 BCNF
在数据库设计的领域中,设计范式是构建高效、规范数据库的关键准则。遵循这些范式,能有效避免数据冗余、插入异常、删除异常等问题,提升数据库的性能与数据完整性。今天,咱们就来深入探讨 1NF、2NF、3NF 和 BCNF 这几种常见的数据库设计范式,并通过具体例子加深理解。
第一范式(1NF)
概念
第一范式要求数据库表的每一列都是不可分割的原子值,即表中的每个单元格都只能包含单一的数据项,不能有重复组或嵌套结构。简单来说,就是确保每列都是最基本的数据单元。
例子
假设我们要设计一个学生信息表,初始设计可能如下:
学号 | 姓名 | 课程(重复组) |
---|---|---|
1001 | 张三 | [数学, 语文] |
1002 | 李四 | [英语, 物理] |
这个设计不符合 1NF,因为“课程”列包含了重复组。按照 1NF 的要求,应将其拆分为:
学号 | 姓名 | 课程 |
---|---|---|
1001 | 张三 | 数学 |
1001 | 张三 | 语文 |
1002 | 李四 | 英语 |
1002 | 李四 | 物理 |
这样,每个单元格都只包含单一数据项,满足了 1NF。
第二范式(2NF)
概念
在满足 1NF 的基础上,2NF 要求表中的每一个非主属性完全依赖于主键,而不能部分依赖于主键。也就是说,如果一个表有复合主键(由多个字段组成的主键),那么非主属性不能只依赖于主键中的一部分字段。
例子
以学生选课系统为例,假设有一个表结构如下:
学号 | 课程号 | 学生姓名 | 课程名称 | 成绩 |
---|---|---|---|---|
1001 | C001 | 张三 | 数学 | 90 |
1002 | C002 | 李四 | 英语 | 85 |
这里主键是(学号,课程号)。“学生姓名”只依赖于“学号”,“课程名称”只依赖于“课程号”,存在部分依赖,不满足 2NF。
拆分后的设计为:
学生表(Student):
学号 | 学生姓名 |
---|---|
1001 | 张三 |
1002 | 李四 |
课程表(Course):
课程号 | 课程名称 |
---|---|
C001 | 数学 |
C002 | 英语 |
选课表(Enrollment):
学号 | 课程号 | 成绩 |
---|---|---|
1001 | C001 | 90 |
1002 | C002 | 85 |
这样,每个表中的非主属性都完全依赖于主键,满足了 2NF。
第三范式(3NF)
概念
在满足 2NF 的基础上,3NF 要求表中的每一个非主属性既不部分依赖于主键,也不传递依赖于主键。传递依赖指的是如果存在 (A \rightarrow B) 和 (B \rightarrow C),那么 (C) 传递依赖于 (A)。
例子
还是以学生选课系统为例,假设在“学生表(Student)”中增加“系别”和“系主任”字段,表结构如下:
学号 | 学生姓名 | 系别 | 系主任 |
---|---|---|---|
1001 | 张三 | 计算机系 | 王老师 |
1002 | 李四 | 数学系 | 李老师 |
这里“系主任”通过“系别”间接依赖于“学号”,存在传递依赖,不满足 3NF。
拆分后的设计为:
学生表(Student):
学号 | 学生姓名 | 系别 |
---|---|---|
1001 | 张三 | 计算机系 |
1002 | 李四 | 数学系 |
系表(Department):
系别 | 系主任 |
---|---|
计算机系 | 王老师 |
数学系 | 李老师 |
此时,消除了传递依赖,满足 3NF。
巴斯 - 科德范式(BCNF)
概念
BCNF 是 3NF 的增强版本,它要求每一个非平凡的函数依赖 (X \rightarrow Y)((Y) 不属于 (X)),(X) 都必须是一个候选键。也就是说,不仅非主属性要依赖于候选键,主属性也要完全依赖于候选键。
例子
假设有一个图书借阅表,表结构如下:
借阅编号 | 图书编号 | 读者编号 | 借阅日期 | 还书日期 | 图书作者 |
---|---|---|---|---|---|
001 | B001 | R001 | 2023 - 01 - 01 | 2023 - 01 - 10 | 作者 A |
002 | B002 | R002 | 2023 - 02 - 01 | 2023 - 02 - 15 | 作者 B |
这里候选键是(借阅编号),但存在函数依赖“图书编号 → 图书作者”,而“图书编号”不是候选键,不满足 BCNF。
拆分后的设计为:
借阅表(Borrow):
借阅编号 | 图书编号 | 读者编号 | 借阅日期 | 还书日期 |
---|---|---|---|---|
001 | B001 | R001 | 2023 - 01 - 01 | 2023 - 01 - 10 |
002 | B002 | R002 | 2023 - 02 - 01 | 2023 - 02 - 15 |
图书表(Book):
图书编号 | 图书作者 |
---|---|
B001 | 作者 A |
B002 | 作者 B |
此时,每个非平凡函数依赖的左边都是候选键,满足 BCNF。
在实际的数据库设计中,理解并遵循这些范式能让我们设计出更优化、更稳定的数据库结构,有效减少数据冗余和异常情况的发生,提升数据库的整体性能和数据管理效率。