数据库三范式详解及示例

263 阅读5分钟

数据库三范式详解及示例

数据库范式(Normal Form)是数据库设计的重要原则,用于规范表结构,减少数据冗余,提高数据一致性。下面详细讲解三大范式的概念、要求和具体示例。

一、第一范式(1NF)

定义

第一范式要求数据库表中的每一列都是不可再分的原子数据项,即每个字段的值只能是单一值,不能包含复合数据。

核心原则

  • 列不能再分成其他几列(原子性)
  • 同一列中不能有多个值
  • 不允许重复的属性
  • 所有字段值必须是标量(如整数、字符串),而非数组或组合

示例

不符合1NF的表:

学生表(Student)
| 学号 | 姓名 | 联系方式          | 年龄 |
|------|------|-------------------|------|
| 101  | 张三 | 电话:123456,邮箱:zs@example.com | 20   |
| 102  | 李四 | 电话:654321,邮箱:ls@example.com | 21   |

问题: 联系方式字段包含了电话和邮箱两个值,不是原子数据项。

符合1NF的修正:

学生表(Student)
| 学号 | 姓名 | 电话    | 邮箱             | 年龄 |
|------|------|---------|------------------|------|
| 101  | 张三 | 123456  | zs@example.com   | 20   |
| 102  | 李四 | 654321  | ls@example.com   | 21   |

注意:现代关系数据库管理系统(DBMS)已经内置了1NF的要求,无法创建不符合1NF的表结构。

二、第二范式(2NF)

定义

第二范式建立在第一范式的基础上,要求所有非主属性必须完全依赖于整个主键(针对复合主键),消除部分依赖。

关键概念

  1. 函数依赖:通过属性A的值,可以确定唯一的B属性值,则B依赖于A(记为A→B)
  2. 完全函数依赖:如果A是属性组,则B的确定需要依赖A中的所有属性值
  3. 部分函数依赖:如果A是属性组,则B的确定只需要依赖A中的部分属性值(需要消除)
  4. 候选码:能够唯一标识元组的属性或属性组

示例

不符合2NF的表:

选课成绩表(Score)
| 学生ID | 课程ID | 课程名称 | 学生姓名 | 成绩 |
|--------|--------|----------|----------|------|
| 101    | C01    | 数学     | 张三     | 90   |
| 101    | C02    | 英语     | 张三     | 85   |
| 102    | C01    | 数学     | 李四     | 88   |

问题:

  • 主键是(学生ID, 课程ID)的复合主键
  • 课程名称只依赖课程ID(主键的一部分)
  • 学生姓名只依赖学生ID(主键的一部分)
  • 这就是部分依赖现象

符合2NF的修正:拆分为三个表

学生表(Student)
| 学生ID | 学生姓名 |
|--------|----------|
| 101    | 张三     |
| 102    | 李四     |

课程表(Course)
| 课程ID | 课程名称 |
|--------|----------|
| C01    | 数学     |
| C02    | 英语     |

成绩表(Score)
| 学生ID | 课程ID | 成绩 |
|--------|--------|------|
| 101    | C01    | 90   |
| 101    | C02    | 85   |
| 102    | C01    | 88   |

注意:单字段主键的表自动满足2NF,因为不存在部分依赖的可能。

三、第三范式(3NF)

定义

第三范式建立在第二范式的基础上,要求所有非主属性必须直接依赖于主键,消除传递依赖。

关键概念

  • 传递函数依赖:如果A→B,且B→C,则C传递依赖于A(需要消除)
  • 第三范式要求数据表的每一列都与主键直接相关,而不是间接相关

示例

不符合3NF的表:

学生信息表(StudentInfo)
| 学号 | 姓名 | 系名     | 系主任   | 系办公室 |
|------|------|----------|----------|----------|
| 101  | 张三 | 计算机系 | 王教授   | 科技楼301|
| 102  | 李四 | 计算机系 | 王教授   | 科技楼301|
| 103  | 王五 | 数学系   | 李教授   | 教学楼205|

问题:

  • 主键是学号
  • 所有非主属性都依赖于学号,满足2NF
  • 但系主任和系办公室直接依赖于系名,而非主键学号
  • 这是传递依赖现象:学号→系名→系主任/系办公室

符合3NF的修正:拆分为两个表

学生表(Student)
| 学号 | 姓名 | 系名     |
|------|------|----------|
| 101  | 张三 | 计算机系 |
| 102  | 李四 | 计算机系 |
| 103  | 王五 | 数学系   |

系信息表(Department)
| 系名     | 系主任   | 系办公室 |
|----------|----------|----------|
| 计算机系 | 王教授   | 科技楼301|
| 数学系   | 李教授   | 教学楼205|

数据库范式的作用与应用

范式的优点

  • 减少数据冗余:避免相同数据在多个地方存储
  • 提高数据一致性:修改一处即可,不会出现不一致
  • 简化数据维护:更容易插入、更新和删除数据
  • 优化查询性能:适当的规范化有助于提高查询效率

实际应用考虑

在实际数据库设计中,有时为了性能考虑,会适当地进行反范式化设计。例如:

  • 为频繁连接查询的表添加冗余字段
  • 预先计算并存储聚合结果
  • 对经常一起查询的字段进行组合存储

反范式化是在性能和规范化之间做出的权衡,需要根据具体业务场景决定。

总结

数据库三范式是递进关系,逐步消除数据冗余问题:

  1. 1NF:消除复合属性,保证列的原子性
  2. 2NF:消除部分依赖,保证非主属性完全依赖主键
  3. 3NF:消除传递依赖,保证非主属性直接依赖主键

通过合理应用数据库范式,可以设计出结构清晰、维护简便、性能良好的数据库系统。