文章目录
- [一: 第一范式(1NF)列不可再分](#一: 第一范式(1NF)列不可再分)
- [二: 第二范式(2NF)消除部分依赖](#二: 第二范式(2NF)消除部分依赖)
- [三: 第三范式(3NF)消除传递依赖](#三: 第三范式(3NF)消除传递依赖)

文章作者:当战神遇到编程
文章专栏:MySQL
欢迎大家点赞👍评论📝收藏⭐文章



范式(Normal Form)是关系型数据库设计的规范,目的是:表设计得更合理,数据不重复,修改更方便。
一: 第一范式(1NF)列不可再分
核心要求:字段必须具有原子性(不可再分)
每一列 只能存一个值,不能存多个值。
不满足第一范式的例子:
| 学号 | 姓名 | 班级名 | 学校信息 |
|---|---|---|---|
| 101 | 张三 | Java一班 | 清华大学, 北京市海淀区, 010-8888 |
满足第一范式的例子(合格的表):
| 学号 | 姓名 | 班级名 | 学校名称 | 学校地址 | 学校电话 |
|---|---|---|---|---|---|
| 101 | 张三 | Java一班 | 清华大学 | 北京市海淀区 | 010-8888 |
注意:
- 数据库的"入场券": 第一范式是关系型数据库的最基本要求。如果不满足 1NF,则不能被称为真正的关系型数据库。
- 原子性的标准: 原子性不是绝对的,而是根据业务需求 决定的。
○ 例如: 如果业务只需要显示全名,那么 姓名 就是原子的;但如果业务需要区分"姓"和"名",那么 姓名 就得拆分为 姓 和 名 两列。
二: 第二范式(2NF)消除部分依赖
核心定义:
在满足第一范式(1NF)的基础上,消除非主键字段对候选键的"部分函数依赖"。
1.必须要懂的底层概念 (术语拆解)
-
候选键 (Candidate Key) vs 主键 (Primary Key) :
○ 候选键 : 表中能唯一标识一行数据的列(或列组合)。
○ 主键 : 从候选键中选出来的"正职"班长。
○ 联合主键 : 由多个列共同组成的唯一主键。此时,单独的每一列只能叫"候选键",合在一起才叫"主键"。
-
函数依赖
○ 完全函数依赖 : 必须通过整个主键 才能确定某个数据。(2NF 要求 )
○ 部分函数依赖 : 只通过主键中的一部分列 ,就能确定某个数据。 ( 2NF 禁止)
2.案例剖析

- 这张表中使用学号 + 课程名定义联合主键来唯一标识一个学生某门课程的成绩
- 这张表中学生姓名只 依赖于学号 ,不 依赖于课程名 ,学分只 依赖于课程名 ,不 依赖于学号,这两个非关键字段都不满足第二范式的核心定义
改正:拆成三个表
学生表
| Id | 学号 | 学生姓名 | 年龄 | 性别 |
|---|---|---|---|---|
| 1 | 10001 | 张三 | 18 | 男 |
| 2 | 10002 | 李四 | 19 | 女 |
| 3 | 10003 | 王五 | 18 | 男 |
课程表
| Id | 课程名 | 学分 |
|---|---|---|
| 1 | MySQL | 50 |
| 2 | Java | 60 |
| 3 | C++ | 60 |
成绩表
| 学生Id | 课程Id | 成绩 |
|---|---|---|
| 1 | 1 | 98 |
| 2 | 1 | 100 |
| 3 | 1 | 89 |
| 1 | 2 | 100 |
| 2 | 2 | 99 |
| 3 | 3 | 98 |
只有单列主键的表通常天然满足第二范式。
如果表没有满足第二范式,可能出现的问题有:
1.数据冗余 :学生的姓名,年龄学分都重复的出现,造成大量的数据冗余
-
更新异常 :假设需要调整MySQL的学分,就需要修改所有记录中关于MySQL的记录.如果部分记录更新失败,就会出现同一课程学分不一致的情况,表现为数据不一致
-
插入异常 :⽬前这样的设计,成绩与每⼀⻔课和学⽣都有对应关系,也就是说只有学⽣参加选修课程考试取得了成绩才能⽣成⼀条记录。当有⼀⻔新课还没有学⽣参加考试取得成绩之前,那么这⻔新课在数据库中是不存在的,因为成绩为空时记录没有意义。
-
删除异常:把毕业学⽣的考试数据全都删除,此时课程和学分的信息也会被删除掉,有可能导致⼀段时间内,数据库⾥没有某⻔课程和学分的信息。
三: 第三范式(3NF)消除传递依赖
定义:在满⾜第⼆范式的基础上,消除非主键字段对非主键字段的依赖(消除传递依赖)。
一、先理解什么叫传递依赖
如果存在:
sql
主键 -> A -> B
说明:
- A 依赖主键
- B 又依赖 A
那么 B 就是间接依赖主键,这叫传递依赖。
举个例子:
| 学号 | 姓名 | 年龄 | 所属学院 | 学院地址 | 学院电话 |
|---|
存在传递依赖:学号-> 所在学院-> 学院电话 ,存在传递依赖的表不满足第三范式。
改正:只需要拆分成两张表。
1.学院表
| 学院编号 | 学院名 | 学院电话 | 学院地址 |
|---|
2.学生表
| 学号 | 姓名 | 年龄 | 学院编号 |
|---|
这样设计后,两张表中的非主键字段都直接依赖各自主键;学生表通过外键(学院编号)与学院表建立关联关系。