数据库设计的三大范式(1NF、2NF、3NF)是为了减少数据冗余、避免数据异常(插入、更新、删除异常)而提出的规范化规则,它们是递进关系(后续范式建立在前置范式满足的基础上)。
一、第一范式(1NF:First Normal Form)
1、定义
第一范式是最基本的范式,数据表中的每一列(属性)必须是不可再分的原子值(即 “列不可拆”),且每个字段只能包含单一的值。
2、核心要求
消除 “复合属性”,确保属性的原子性。
3、不满足 1NF 的例子
表1、 联系方式 同时存储 电话 和 邮箱
| 学号 | 姓名 | 联系方式 |
|---|---|---|
| 1 | 张三 | 电话:123456; 邮箱:abc@gmail,com |
表2、列重复,课程1、课程2及课程3
| 学号 | 姓名 | 课程1 | 课程2 | 课程3 |
|---|---|---|---|---|
| 1 | 张三 | 语文 | 数学 | |
| 2 | 李四 | 数学 | 英语 | |
| 3 | 王五 | 语文 | 英语 | |
| 4 | 宋六 | 语文 | 数学 | 英语 |
表3、每列含重复数据
| 学号 | 姓名 | 课程 |
|---|---|---|
| 1 | 张三 | 语文 |
| 2 | 张三 | 数学 |
| 3 | 李四 | 数学 |
| 4 | 李四 | 英语 |
| 5 | 王五 | 语文 |
| 6 | 王五 | 英语 |
| 7 | 宋六 | 语文 |
| 8 | 宋六 | 数学 |
| 9 | 宋六 | 英语 |
4、存在问题
-
解析复杂:复合属性查询时需拆分(如表1中单独获取 邮箱)
-
数据冗余:新增操作会产生大量无效数据(如表2增加新课程,就需要在增加一列,导致大量无效数据)
-
更新复杂:更新数据时需要更新所有相关内容(如表1更新 电话,还需要带上 邮箱、表3更新宋六 姓名,需要更新所有数据行)
5、满足 1NF 的修正
将 联系方式 拆分为 电话 和 邮箱 两个原子列:
| 学号 | 姓名 | 电话 | 邮箱 |
|---|---|---|---|
| 1 | 张三 | 123456 | abc@gmail.com |
二、第二范式(2NF:Second Normal Form)
1、定义
在满足 1NF 的基础上,数据表中所有非主属性(非主键的列)必须完全依赖于主键,而非仅依赖主键的一部分(主要针对联合主键而言)。简而言之就是:一个表中只能保存一种数据,不可以把多种数据保存在同一张数据库表中。
2、核心要求
消除 “部分依赖”(非主属性仅依赖复合主键的某一部分)。
3、关键概念
-
主键:唯一标识记录的列(可能是单一列,也可能是多列组合的 “复合主键”)。
-
完全依赖:非主属性必须依赖于主键的所有字段(若主键是复合的,缺一不可)。
-
部分依赖:非主属性仅依赖复合主键中的某一个或几个字段(而非全部)。
4、不满足 2NF 的例子
表1、订单明细表
| 订单 ID | 商品 ID | 订单日期 | 商品名称 | 数量 | 单价 |
|---|---|---|---|---|---|
| 001 | p1 | 2025-10-01 | 面包 | 1 | 10 |
| 001 | p2 | 2025-10-01 | 牛奶 | 2 | 6 |
| 002 | p1 | 2025-10-02 | 面包 | 2 | 20 |
订单 ID 与 商品 ID 组成联合主键,订单 ID 和 商品 ID、订单日期 是一一对应的,商品名称 与 商品ID 是一一对应的,违反了第二范式。
非主属性 订单日期 仅依赖 订单 ID,与 商品 ID 无关,为部分依赖。
非主属性 商品名称、单价 仅依赖 商品 ID、与 订单 ID 无关,为部分依赖。
5、存在问题
-
数据冗余:订单日期 随同一订单的每个商品重复存储,如 001 的订单日期在两条记录中重复,商品名称、单价 随同一商品的每个订单重复存储。
-
插入异常:若新增一个订单(如 003),但尚未添加商品(无商品 ID),因主键不完整(缺少商品 ID),无法插入订单信息(如订单日期)。
-
更新异常:若 001 的订单日期改为 2025-10-02,需修改该订单下所有商品的记录,否则部分记录日期错误,易遗漏。
-
删除异常:若删除 001 的所有商品记录(如 p1 和 p2),订单 001 的日期信息也会被同时删除,导致订单历史丢失。
6、满足 2NF 的修正
拆分为三张表:
-
订单表(主键:订单 ID):订单 ID、订单日期。
订单 ID 订单日期 001 2025-10-01 001 2025-10-01 002 2025-10-02 -
商品表(主键:商品 ID):商品 ID、商品名称、单价。
商品 ID 商品名称 单价 p1 面包 10 p2 牛奶 6 p1 面包 20 -
订单明细表(主键:订单 ID + 商品 ID):订单 ID、商品 ID、数量。
订单 ID 商品 ID 数量 001 p1 1 001 p2 2 002 p1 2
三、第三范式(3NF:Third Normal Form)
1、定义
在满足 2NF 的基础上,数据表中所有非主属性不依赖于其他非主属性,都和主键直接相关,即非主属性之间不能存在依赖关系,消除 “传递依赖”。
2、核心要求
非主属性只能直接依赖于主键,不能通过其他非主属性间接依赖于主键(即不允许 A 依赖主键,B 依赖 A)。
3、不满足 3NF 的例子
表1、学生信息表
| 学号 | 姓名 | 班级 | 班主任 |
|---|---|---|---|
| 001 | 张三 | 一班 | 王老师 |
| 002 | 李四 | 一班 | 王老师 |
| 003 | 王五 | 二班 | 赵老师 |
主键是 学号。非主属性 班级 依赖于 学号,符合2NF,但是非主属性 班主任 依赖于 班级,而非直接依赖于 学号,及 班主任→班级→学号 存在依赖传递,不符合3NF。
5、存在问题
-
数据冗余:班级 和 班主任 随同学生重复存储(如 一班 的 王老师 在两条记录中重复)。
-
插入异常:若新增一个 班级(三班、尚未有学生),因缺少 学号(主键),无法插入 班级 和 班主任 的信息。
-
更新异常:若将 一班 的 班主任 更换为 宋老师,需修改所有一班学生的 班主任 字段,易遗漏。
-
删除异常:若删除 一班 的所有学生记录,一班 和 王老师 的信息也会被删除,导致信息丢失。
6、满足 3NF 的修正
拆分表以消除传递依赖:
-
学生表(主键:学号):学号、姓名、班级。
学号 姓名 班级 001 张三 一班 002 李四 一班 003 王五 二班 -
班级表(主键:班级):班级、班主任。
班级 班主任 一班 王老师 二班 赵老师
四、总结
三大范式的核心目标是通过消除数据冗余(重复存储),避免插入 / 更新 / 删除异常。实际设计中需平衡规范化与查询效率(过度规范化可能导致多表关联查询复杂),但基础的三大范式是数据库设计的重要原则。
3318

被折叠的 条评论
为什么被折叠?



