数据库范式
数据库范式
- 数据库范式,本质上是一套“数据整理的物理学定律”。它不关心你业务多酷炫,只关心一件事:如何让数据结构更干净、更一致、更少冗余。
第一范式(1NF)
*字段必须是原子值(不可再分)。
比如你建一个学生表:
| 学号 | 姓名 | 电话 |
|---|---|---|
| 1 | 张三 | 123,456 |
电话存两个号码违反1NF,因为一个字段里放了多个值。
正确做法要么拆成:
| 学号 | 姓名 | 电话 |
|---|---|---|
| 1 | 张三 | 123 |
| 1 | 张三 | 456 |
要么单独建电话表。
第二范式(2NF)
核心思想:消除部分依赖。
如果一个表的主键是“联合主键”,那么非主键字段必须依赖整个主键,而不是只依赖一部分。
举个例子:
| 学号 | 课程号 | 学生姓名 | 课程名称 | 成绩 |
主键是(学号 + 课程号)。
问题来了:
- 学生姓名只依赖“学号”
- 课程名称只依赖“课程号”
这叫部分依赖。
结果就是:同一个学生选 10 门课,姓名重复 10 次。
解决方法:拆表。
学生表
课程表
选课表
2NF解决的是“局部重复”问题。
第三范式(3NF)
核心思想:消除传递依赖。
传递依赖是这样:
A → B
B → C
那 A → C 就是传递依赖。
举例:
| 学号 | 姓名 | 系号 | 系名称 |
- 学号 → 系号
- 系号 → 系名称
于是:学号 → 系名称(传递)
问题:系名称被重复存储。
解决方法:再拆:
学生表(学号,姓名,系号)
系表(系号,系名称)
3NF解决的是“间接重复”。
面试角度总结(Java 后端常考)
-
范式的目的是什么?
- 减少冗余
- 避免更新异常
- 提高数据一致性
-
1NF、2NF、3NF区别?
- 1NF:字段必须是原子值;不能一个字段存多个值。解决的是“数据格式混乱”。
- 2NF:消除部分依赖;非主键字段必须完全依赖整个主键。解决的是“局部重复”。
- 3NF:消除传递依赖;非主键字段不能依赖另一个非主键字段。解决的是“间接重复”。
- 记忆逻辑可以这样理解:
- 1NF 管格式
- 2NF 管主键依赖
- 3NF 管非主键之间的依赖
-
为什么实际项目不完全遵守?
- 性能考虑
- 业务复杂度
- 维护成本
