type
status
date
slug
summary
tags
category
icon
password
数据库三范式(3NF)是数据库设计中的一种规范化形式,用于减少数据冗余并提高数据的完整性。三范式包括以下三个层次:第一范式(1NF)、第二范式(2NF)和第三范式(3NF)。要符合第三范式,数据库首先必须符合前两个范式的要求。
第一范式(1NF)
第一范式要求每一个列中的值都是不可分割的原子值,这意味着表中的每一个字段都必须是不可再分的最小数据单位。
要求:
- 表中的每一列都应该只包含单一值。
- 每一列中的值应该是同质的(即同一列中的值应该属于同一数据类型)。
例子:
不符合1NF的表:
符合1NF的表:
第二范式(2NF)
第二范式(2NF)要求每个非主键列只依赖于主键而不依赖于其他非主键列,具体的应用场景是联合主键(多个字段共同充当表的主键),这里通过以下例子来进行说明(订单编号和产品编码组成联合主键):
订单编号 | 产品编号 | 购买价格 | 购买数量 | 订单总金额 | 购买时间 |
202311212056485430000001 | 202311212056485430000003 | 100.00 | 2 | 230 | 2023/11/21 20:56:48 |
202311212056485430000001 | 202311212056485430000004 | 30.00 | 1 | 230 | 2023/11/21 20:56:48 |
202311231036360980000202 | 202311212056485430000005 | 9.99 | 1 | 34.99 | 2023/11/23 10:36:36 |
202311231036360980000202 | 202311212056485430000006 | 10.00 | 1 | 34.99 | 2023/11/23 10:36:36 |
202311231036360980000202 | 202311212056485430000007 | 15.00 | 1 | 34.99 | 2023/11/23 10:36:36 |
直接看感觉没有什么毛病,但是我们来对上表的字段进行分析:
- 购买价格:购买价格完全依赖订单编号+产品编号,订单编号+产品编号同时确定才能确定购买价格(同一产品在不同的订单会有不同的价格);
- 购买数量:购买数量完全依赖订单编号+产品编号;订单编号+产品编号同时确定才能确定购买数量;
- 订单总金额:订单总金额只依赖于订单编号,和实际的产品没有关系,我们通过订单编号就可以明确订单总金额;所以该字段违背了第二范式(2NF);
- 购买时间:购买时间只依赖于订单编号,一个订单的所有商品肯定是同一时间购买的,该字段很明显和产品编号是无任何依赖关系的;所以该字段也违背了第二范式(2NF)。
现在我们进行优化,进行表拆分,拆分后得到两个表:
订单编号 | 产品编号 | 购买价格 | 购买数量 |
202311212056485430000001 | 202311212056485430000003 | 100.00 | 2 |
202311212056485430000001 | 202311212056485430000004 | 30.00 | 1 |
202311231036360980000202 | 202311212056485430000005 | 9.99 | 1 |
202311231036360980000202 | 202311212056485430000006 | 10.00 | 1 |
202311231036360980000202 | 202311212056485430000007 | 15.00 | 1 |
订单编号 | 订单总金额 | 购买时间 |
202311212056485430000001 | 230 | 2023/11/21 20:56:48 |
202311231036360980000202 | 34.99 | 2023/11/23 10:36:36 |
这样拆分完后,就符合了第二范式(2NF),同时数据结构更加清晰,也减少了数据冗余。
第三范式(3NF)
第三范式(3NF)说直白点就是表中的非主键字段和主键字段直接相关,不允许间接相关。下面通过一个表来进行说明(主键:部门ID)。
部门ID | 部门名称 | 负责人 | 负责人性别 | 负责人年龄 |
202311212056485430000001 | 综合支撑部 | 张三 | 男 | 35 |
202311212056485430000002 | 人力资源部 | 李四 | 男 | 41 |
很明显,部门名称和负责人和部门ID是直接关联了,而负责人性别和负责人年龄和部门ID并没有直接关系,而是和负责人直接关联的,所以就存在这种传递依赖关系了。
部门ID->负责人->负责人性别 部门ID->负责人->负责人年龄
这就违反了第三范式(3NF),这个时候就需要把上表拆分成两张表,以外键形式关联。如下所示:
部门ID | 部门名称 | 负责人ID |
202311212056485430000001 | 综合支撑部 | 202311212056485430000003 |
202311212056485430000002 | 人力资源部 | 202311212056485430000004 |
负责人ID | 姓名 | 性别 | 年龄 |
202311212056485430000003 | 张三 | 男 | 35 |
202311212056485430000004 | 李四 | 男 | 41 |
这样拆分后,结构立马清晰了,每个表存储的数据也都是单一的。
- 作者:Yohann
- 链接:https://yohann.19990617.xyz/article/db3nf
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
相关文章