第一范式(1NF) - 原子性

第一范式(1NF)要求表中的每个字段(列)必须是原子的,即每个列的值不能是集合、数组或其他可以分解的多个值。表中的每个单元格只能包含一个值,而不能包含多个值。

1NF 要求:
  • 表中的每列的值都是不可再分割的原子值。
  • 每行必须是唯一的,不能有重复的行

不满足,违反原子性

学号 姓名 科目
001 张三 数学, 英语
002 李四 语文, 数学

解决方法

学号 姓名 科目
001 张三 数学
001 张三 英语
002 李四 语文
002 李四 数学

第二范式(2NF) - 消除部分依赖

第二范式(2NF)要求表格不仅符合 第一范式(1NF),还要消除 部分依赖。2NF 解决的是 非主属性(非关键字属性)部分依赖于 主键 的问题

2NF 要求:
  • 表必须首先满足 第一范式
  • 非主属性(即不包含在候选键中的属性)必须完全依赖于 主键,而不能仅依赖于主键的一部分。

假设有一个学生课程成绩表,主键是 (学号, 课程)姓名 只依赖于 学号,而与 课程 无关。姓名 依赖于 学号,而不是 学号 + 课程(主键的组合),因此 姓名 不是完全依赖于主键,出现了部分依赖

学号 课程 姓名 成绩
001 数学 张三 85
001 英语 张三 90
002 数学 李四 80
002 英语 李四 88

解决方法

将其转换为 2NF 后,可以将 姓名 提取到另一个表中,形成两个表:

学生表(存储学号和姓名):

学号 姓名
001 张三
002 李四

成绩表(存储学号、课程和成绩):

学号 课程 成绩
001 数学 85
001 英语 90
002 数学 80
002 英语 88

第三范式(3NF) - 消除传递依赖

第三范式(3NF)要求表格不仅符合 第二范式(2NF),还要消除 传递依赖。传递依赖是指非主属性依赖于其他非主属性,而不是直接依赖于主键。

3NF 要求:
  • 表必须首先满足 第二范式(2NF)
  • 非主属性必须直接依赖于 主键,而不能依赖于其他非主属性。

假设有一个员工表,其中包含了员工的 部门名称部门地址,其中 部门地址 依赖于 部门名称,而 部门名称 又依赖于 员工(主键)。

在这个表中,部门地址 依赖于 部门名称,而 部门名称 依赖于主键 员工ID,这就造成了传递依赖,即 员工ID → 部门名称 → 部门地址

员工ID 员工姓名 部门名称 部门地址
001 张三 销售部 北京市朝阳区
002 李四 技术部 上海市浦东新区
003 王五 销售部 北京市朝阳区

解决方法

部门信息 提取到另一个单独的表中。

员工表(存储员工ID、姓名和部门ID):

员工ID 员工姓名 部门ID
001 张三 D1
002 李四 D2
003 王五 D1

部门表(存储部门ID、部门名称和部门地址):

部门ID 部门名称 部门地址
D1 销售部 北京市朝阳区
D2 技术部 上海市浦东新区

4. BC范式(BCNF)- 消除主键外的决定因素

BCNF 是比第三范式(3NF)更严格的范式,其核心目标是消除所有 非主属性对候选键的部分依赖或传递依赖,同时确保所有函数依赖的 决定因素(左侧属性) 必须是 候选键

BCNF 要求:

  • 所有非平凡函数依赖 的左侧(决定因素)必须是 候选键
  • 若存在X → Y的依赖,则 X 必须是候选键

其中主键为 仓库名 和 物品名 的组合,同时 管理员 和 物品名 的组合是候选键

管理员的名字可以决定仓库名,那么这个候选键中的主属性就影响到主键中的属性了。
主键中的主属性对于候选键是部分依赖关系,这可能导致插入、删除和更新数据时产生异常。

仓库名 管理员 物品名 数量
北京仓 张三 iPhone XR 10
北京仓 张三 iPhone 8P 20
上海仓 李四 iPhone 8 30
上海仓 李四 iPhone 7 40

解决方案

表拆成两张表

仓库 表

仓库名 物品名 数量
北京仓 iPhone XR 10
北京仓 iPhone 8P 20
上海仓 iPhone 8 30
上海仓 iPhone 7 40

仓库-管理员 表

仓库名 管理员
北京仓 张三
北京仓 张三
上海仓 李四
上海仓 李四

总结

  • 第一范式(1NF):要求每个字段的值都是原子性的,不可再分。
  • 第二范式(2NF):要求满足 1NF,并且消除部分依赖,即非主属性必须完全依赖于主键。
  • 第三范式(3NF):要求满足 2NF,并且消除传递依赖,即非主属性只能依赖于主键,不能依赖于其他非主属性。

在实际的数据库设计过程中,通常会逐步满足这些范式,以达到数据的规范化

主要用于规范化数据表结构,减少数据冗余,提升数据库的查询效率和一致性。

范式是递进的关系