三大范式,让数据库更规范、高效!
三大范式,让数据库更规范、高效!
数据库的三大范式是数据库设计的基础,它们分别是第一范式(1NF)、第二范式(2NF)和第三范式(3NF)。这些范式旨在解决数据冗余、更新异常、插入异常和删除异常等问题,通过将数据库表分解成更小的、更规范的表,可以减少数据冗余,避免更新、插入和删除异常,从而提高数据的完整性和一致性。
一、为什么要使用范式?
在讲解三大范式之前,我们先来了解一下为什么要使用范式。
- 数据冗余:同一个数据在数据库中多次出现,浪费存储空间。
- 更新异常:修改一个数据时,需要修改多个地方,容易出现数据不一致的情况。
- 插入异常:插入一条新的数据时,可能需要插入一些不必要的信息。
- 删除异常:删除一条数据时,可能导致一些有用的信息也被删除。
范式就是为了解决这些问题而提出的。通过将数据库表分解成更小的、更规范的表,可以减少数据冗余,避免更新、插入和删除异常,从而提高数据的完整性和一致性。
二、第一范式 (1NF)
想象一下,你有一个表格,表格的每一列都只能放一个东西,不能把多个东西放在同一列里。第一范式就是要求数据库表的每一列都是原子性的,也就是说,每一列都不能再分解成更小的部分。
例子:
假设我们有一个 “订单” 表,其中有一列 “商品”,存储了订单中所有商品的名称,用逗号分隔:
订单ID 客户ID 商品
1 101 苹果,香蕉,梨
2 102 橙子,葡萄
这个表不符合第一范式,因为 “商品” 列可以再分解成 “苹果”、“香蕉”、“梨” 等更小的部分。
为了满足第一范式,我们需要把 “订单” 表分解成两个表:“订单” 表和 “订单商品” 表:
订单表:
订单ID 客户ID
1 101
2 102
订单商品表:
订单ID 商品名称
1 苹果
1 香蕉
1 梨
2 橙子
2 葡萄
现在,“订单商品” 表的每一列都是原子性的,符合第一范式。
总结:
- 每一列都是不可再分的原子数据项。
- 简单来说,就是避免一列中出现多个值。
三、第二范式 (2NF)
想象一下,你有一个表格,表格里有一些信息是依赖于整个表格的,而不是只依赖于表格的一部分。第二范式就是要求数据库表必须满足第一范式,并且非主属性必须完全依赖于主键。
- 主键:能够唯一标识表中每一行数据的属性或属性组合。
- 非主属性:除了主键以外的其他属性。
- 完全依赖:非主属性必须依赖于整个主键,而不是只依赖于主键的一部分。
例子:
假设我们有一个 “订单商品” 表,其中包含以下信息:
订单ID 商品ID 商品名称 商品价格
1 1 苹果 5
1 2 香蕉 3
2 1 苹果 5
2 3 橙子 4
这个表的主键是 (订单ID, 商品ID)。
在这个表中,“商品名称” 依赖于 “商品ID”,而不是依赖于整个主键 (订单ID, 商品ID)。也就是说,只要 “商品ID” 确定了,“商品名称” 也就确定了,与 “订单ID” 无关。这违反了第二范式。
为了满足第二范式,我们需要把 “订单商品” 表分解成两个表:“订单商品” 表和 “商品” 表:
订单商品表:
订单ID 商品ID 商品价格
1 1 5
1 2 3
2 1 5
2 3 4
商品表:
商品ID 商品名称
1 苹果
2 香蕉
3 橙子
现在,“订单商品” 表的非主属性 “商品价格” 完全依赖于主键 (订单ID, 商品ID),“商品” 表的非主属性 “商品名称” 完全依赖于主键 “商品ID”,符合第二范式。
总结:
- 必须满足第一范式。
- 非主属性必须完全依赖于主键。
- 消除部分依赖。
四、第三范式 (3NF)
想象一下,你有一个表格,表格里有一些信息是可以通过其他信息推导出来的,而不是直接依赖于表格的主键。第三范式就是要求数据库表必须满足第二范式,并且非主属性之间不能存在传递依赖。
- 传递依赖:非主属性 A 依赖于非主属性 B,非主属性 B 依赖于主键,那么非主属性 A 就传递依赖于主键。
例子:
假设我们有一个 “订单” 表,其中包含以下信息:
订单ID 客户ID 客户姓名 客户电话
1 101 张三 13800000000
2 102 李四 13900000000
这个表的主键是 “订单ID”。
在这个表中,“客户姓名” 和 “客户电话” 都依赖于 “客户ID”,而不是直接依赖于 “订单ID”。也就是说,只要 “客户ID” 确定了,“客户姓名” 和 “客户电话” 也就确定了,与 “订单ID” 无关。这违反了第三范式。
为了满足第三范式,我们需要把 “订单” 表分解成两个表:“订单” 表和 “客户” 表:
订单表:
订单ID 客户ID
1 101
2 102
客户表:
客户ID 客户姓名 客户电话
101 张三 13800000000
102 李四 13900000000
现在,“订单” 表的非主属性 “客户ID” 直接依赖于主键 “订单ID”,“客户” 表的非主属性 “客户姓名” 和 “客户电话” 直接依赖于主键 “客户ID”,符合第三范式。
总结:
- 必须满足第二范式。
- 非主属性之间不能存在传递依赖。
- 消除传递依赖。
五、总结
- 1NF:每一列都是原子性的。
- 2NF:非主属性完全依赖于主键。
- 3NF:非主属性之间不存在传递依赖。
三大范式是数据库设计的基础,掌握它们可以帮助我们设计出更规范、更高效的数据库。