数据库的三范式(3NF)是数据库设计中用来规范和优化数据表结构的一系列规则。这些规则有助于减少数据冗余、消除数据异常,并提高数据库的效率和一致性。以下是对三范式的详细解释:
一、第一范式
(1NF)
定义:第一范式要求数据库表中的每一列都必须是原子性的(即不可再分),并且表中的每个字段只能包含一个值。
要求:
表中的每一列必须是不可再分割的独立数据项。
每一行必须有唯一的标识(通常为主键)。
确保数据表中每列(字段)的原子性。
如果数据表中每个字段都是不可再分的最小数据单元,则满足第一范式。
例如:user用户表,包含字段id,username,password
例子: 假设有一个包含学生信息的表:
| 学生ID | 姓名 | 电话号码 |
|--------|--------------|---------------------|
| 1 | 张三 | 123456, 789012 |
| 2 | 李四 | 345678 |
不符合 1NF:电话号码 列包含多个电话号码。
转换为 1NF:
| 学生ID | 姓名 | 电话号码 |
|--------|--------------|-----------|
| 1 | 张三 | 123456 |
| 1 | 张三 | 789012 |
| 2 | 李四 | 345678 |
二、第二范式
(2NF)
定义:在满足第一范式的基础上,第二范式要求每个非主属性必须完全依赖于主键,不能有部分依赖关系。
要求:
表必须首先满足第一范式。
表中的非主属性必须完全依赖于整个主键,而不能依赖于主键的一部分。
在第一范式的基础上更进一步,目标是确保表中的每列都和主键相关。
如果一个关系满足第一范式,并且除了主键之外的其他列,都依赖于该主键,则满足第二范式。
例如:一个用户只有一种角色,而一个角色对应多个用户。则可以按如下方式建立数据表关系,使其满足第二范式。
user用户表,字段id,username,password,role_id
role角色表,字段id,name
用户表通过角色id(role_id)来关联角色表
例子: 假设有一个包含课程成绩的表:
| 学生ID | 课程ID | 成绩 | 学生姓名 |
|--------|--------|------|----------|
| 1 | 101 | 85 | 张三 |
| 2 | 102 | 90 | 李四 |
不符合 2NF:学生姓名 只依赖于 学生 ID,而不是整个主键 (学生 ID, 课程 ID)。
转换为2NF: 拆分为两个表:
学生表:
| 学生ID | 学生姓名 |
|--------|----------|
| 1 | 张三 |
| 2 | 李四 |
成绩表:
| 学生ID | 课程ID | 成绩 |
|--------|--------|------|
| 1 | 101 | 85 |
| 2 | 102 | 90 |
三、第三范式
(3NF)
定义:在满足第二范式的基础上,第三范式要求表中的非主属性必须直接依赖于主键,而不能依赖于其他非主属性(即不存在传递依赖)。
要求:
表必须首先满足第二范式。
非主属性之间不能有传递依赖。
在第二范式的基础上更进一步,目标是确保表中的列都和主键直接相关,而不是间接相关。
例如:一个用户可以对应多个角色,一个角色也可以对应多个用户。则可以按如下方式建立数据表关系,使其满足第三范式。
user用户表,字段id,username,password
role角色表,字段id,name
user_role用户-角色中间表,id,user_id,role_id
像这样,通过第三张表(中间表)来建立用户表和角色表之间的关系,同时又符合范式化的原则,就可以称为第三范式。
例子: 假设有一个包含学生信息的表:
| 学生ID | 班级ID | 班级名 | 学生姓名 |
|--------|--------|--------|----------|
| 1 | 1001 | 计算机 | 张三 |
| 2 | 1002 | 数学 | 李四 |
不符合 3NF:班级名 依赖于 班级 ID,而 班级 ID 依赖于 学生 ID(传递依赖)。
转换为 3NF: 拆分为两个表:
学生表:
| 学生ID | 班级ID | 学生姓名 |
|--------|--------|----------|
| 1 | 1001 | 张三 |
| 2 | 1002 | 李四 |
班级表:
| 班级ID | 班级名 |
|--------|---------|
| 1001 | 计算机 |
| 1002 | 数学 |
四、反范式化
反范式化指的是通过增加冗余或重复的数据来提高数据库的读性能。
例如:在上例中的 user_role 用户-角色中间表增加字段 role_name。
反范式化可以减少关联查询时,join 表的次数。
五、总结
**第一范式 (1NF)**:确保每列都是原子性的,且每列数据不可分割。
**第二范式 (2NF)**:在满足 1NF 的基础上,确保每个非主属性完全依赖于主键。
**第三范式 (3NF)**:在满足 2NF 的基础上,确保非主属性不依赖于其他非主属性,消除传递依赖。
通过应用这些范式,可以帮助设计出更具逻辑性、更加规范的数据库结构,减少数据冗余和维护复杂性。
mysql 第1.9章 创建-三大范式和反范式