什么是三大范式
三大范式是数据库设计遵循的规范, 分别是:
- 第一范式(1NF):表中每列不可再拆分
- 第二范式(2NF):1NF基础上,要求非主键列完全依赖于主键,不能只依赖于主键的一部分(针对联合主键)
- 第三范式(3NF):2NF基础上, 要求任何非主键列必须直接依赖于主键,不能是传递依赖
为什么要有三大范式
减少数据冗余,保持数据一致性和完整性。
1NF
例: 有一个学生表,address字段的值为江苏省南京市雨花台区XX街道XX小区
id | name | address |
---|---|---|
1 | 张三 | 江苏省南京市雨花台区XX街道XX小区 |
此时如果需要把学生按省,市,区分类, 无法满足需求;这里可以把address字段可以继续拆分为province, city, area, address,实现1NF
id | name | province | city | area | address |
---|---|---|---|---|---|
1 | 张三 | 江苏 | 南京 | 雨花台 | XX街道XX小区 |
2NF
例: 有一个学生课程表
学号(主键) | 课程(主键) | 教师姓名 | 成绩 | 学生姓名 | 专业 |
---|---|---|---|---|---|
1001 | C语言 | 张三 | 80 | 李四 | 金融工程 |
1002 | JAVA | 王五 | 66 | 王二 | 计算机科学与技术 |
从上表看出, 教师姓名,成绩依赖于学号和课程,但学生姓名和专业仅依赖于学号,不依赖于课程,不符合2NF
可以拆成如下两张表,实现2NF
学号(主键) | 课程(主键) | 教师姓名 | 成绩 |
---|---|---|---|
1001 | C语言 | 张三 | 80 |
1002 | JAVA | 王五 | 66 |
学号(主键) | 学生姓名 | 专业 |
---|---|---|
1001 | 李四 | 金融工程 |
1002 | 王二 | 计算机科学与技术 |
3NF
例:有个学生表(学号,姓名,学院,学院地点,学院电话), 学号为主键。
这个数据库符合2NF,但不符合3NF,因为(学院地点,学院电话)依赖于学院,需要把表拆分为如下两个表,以符合3NF:
- 学生表(学号,姓名,学院)
- 学院表(学院,学院地点,学院电话)
什么场景可以不遵循三大范式
为了提高查询效率,有时需要适当保留冗余数据,不必严格遵循三大范式
例: 订单表中添加”总金额”字段,”总金额”可以通过”数量”乘以”单价”得到,是冗余字段,不符合3NF。但是增加这个冗余字段,可以提高查询速度。