文章目录
- 简介
- 什么是范式
- 最常用的范式
- 第一范式 - 1NF
- 第二范式 - 2NF
- 第三范式 - 3NF
- 第四范式 - 4NF
- 第五范式 - 5NF
- 巴斯-科德范式 - BCNF
- 总结
简介
什么是范式
范式(Normal Form,简称NF)是数据库设计时遵循的一种规范,不同的规范要求遵循不同的范式。
数据库范式是数据库设计表结构所遵循的规范和指导方法,目的是为了减少冗余,建立结构合理的数据库,从而提高数据存储和使用的性能。
最常用的范式
最常用的范式是三大范式,即第一范式、第二范式、第三范式。这三大范式之间是具有依赖关系的。每个范式都是用来规定某种结构或数据要求,后一范式都是在前一范式已经满足的情况用来“加强要求”。比如第二范式是在第一范式的基础上建设的,第三范式是在第二范式的基础上建设的。
第一范式 - 1NF
符合1NF的关系中的每个属性都不可再分。即表中字段的数据,均不可再拆分,遵循原子性。具体来说,第一范式要求数据库表的每一列都是不可分割的原子数据项,而不能是集合、数组、记录等非原子数据项。
举例,员工表信息如下:
编号 | 姓名 | 性别 |
---|---|---|
001 | 技术部张三 | 男 |
002 | 技术部李四 | 男 |
003 | 行政部王五 | 女 |
上表中姓名字段中的数据是可以继续拆分的,因此它不符合第一范式。那么怎么优化才符合第一范式呢?将姓名字段拆分即可,优化结果如下:
编号 | 部门 | 姓名 | 性别 |
---|---|---|---|
001 | 技术部 | 张三 | 男 |
002 | 技术部 | 李四 | 男 |
003 | 行政部 | 王五 | 女 |
那么是否遵循第一范式就更好呢?
编号 | 姓名 | 家庭地址 |
---|---|---|
001 | 张三 | 江西省南昌市东湖区 |
002 | 李四 | 广东省佛山市禅城区 |
003 | 王五 | 湖北省武汉市新洲区 |
观察该表,我们发现家庭地址可以继续拆分,拆分结果如下:
编号 | 姓名 | 省 | 市 | 区 |
---|---|---|---|---|
001 | 张三 | 江西省 | 南昌市 | 东湖区 |
002 | 李四 | 广东省 | 佛山市 | 禅城区 |
003 | 王五 | 湖北省 | 武汉市 | 新洲区 |
看上去,拆分以后更符合第一范式。但如果项目中只需要使用一个完整的家庭地址呢?明显不拆分更简单好用。
所以范式只是给我们一个参考,更多的需要根据项目实际情况来进行设计。
第二范式 - 2NF
在满足第一范式的基础上,要求表中的非主键列必须安全依赖于主键,而不是依赖于主键的一部分。这有助于减少数据冗余,并确保数据的一致性。即,一张表只描述一件事情,遵循唯一性。
举例,学生成绩表如下:
学号 | 姓名 | 年龄 | 课程名称 | 成绩 | 学分 |
---|---|---|---|---|---|
001 | 小张 | 28 | 语文 | 90 | 3 |
001 | 小张 | 28 | 数学 | 100 | 2 |
002 | 小黄 | 25 | 语文 | 95 | 3 |
002 | 小黄 | 25 | 数学 | 90 | 2 |
003 | 小高 | 22 | 数学 | 95 | 2 |
- 姓名和年龄依赖于学号
- 学分依赖于课程名称
- 成绩依赖于学号和课程名称,如果学号和课程名称是联合主键,那么它们可以确定联合主键以外的所有非主键值。但姓名、年龄、学分部分依赖于主键的一部分,所以该表只符合第一范式,不符合第二范式。
那么如何调整上述表才能符合第二范式呢?基于上述三种主键可能,将表拆分成三个。
- 学生表
学号 | 姓名 | 年龄 |
---|---|---|
001 | 小张 | 28 |
002 | 小黄 | 25 |
003 | 小高 | 22 |
- 课程表
课程名称 | 学分 |
---|---|
语文 | 3 |
数学 | 2 |
- 成绩表
学号 | 课程名称 | 成绩 |
---|---|---|
001 | 语文 | 90 |
001 | 数学 | 100 |
002 | 语文 | 95 |
002 | 数学 | 90 |
003 | 数学 | 95 |
那么,为什么要遵循第二范式呢?如果不遵循第二范式,会有什么问题呢?
- 数据冗余过大
如上表,学生表和课程表分别有3条数据、2条数据。如果数据都放在一张表中,姓名、年龄、课程名称、学分数据就在表中大量冗余。 - 插入异常
假如学号和课程名称是主键,现在计划新开设一门科学课,暂时还没有学生,由于缺少学号主键信息,就无法正常插入数据。 - 更新不方便
假如数学课程的学分发生变化,则需要把表中关于该课程的学分全部更新。如果拆分出课程表,只需要更新一条记录。 - 删除异常
假如把所有学生的数学成绩删除,那么所有与数学课程相关的数据也随之消失了。学生的数学成绩没了,并不表示这门数学课也没了。
第三范式 - 3NF
在满足第二范式的基础上,要求任何非主键列不能传递依赖于主键。也就是说,非主键列必须直接依赖于主键,而不是通过其他非主键列间接依赖于主键,遵循独立性。这有助于进一步消除数据冗余和更新异常。
编号 | 部门 | 姓名 | 性别 | 部门经理 |
---|---|---|---|---|
001 | 技术部 | 张三 | 男 | 王经理 |
002 | 技术部 | 李四 | 男 | 王经理 |
003 | 行政部 | 王五 | 女 | 李经理 |
上表符合第二范式,但是在非主键字段中,部门经理依赖于部门,所以不符合第三范式。那怎么调整才符合第三范式呢?答案是拆成两张表,消除依赖传递。
- 员工表
编号 | 部门 | 姓名 | 性别 |
---|---|---|---|
001 | 技术部 | 张三 | 男 |
002 | 技术部 | 李四 | 男 |
003 | 行政部 | 王五 | 女 |
- 部门表
部门 | 部门经理 |
---|---|
技术部 | 王经理 |
行政部 | 李经理 |
第四范式 - 4NF
在第三范式的基础上,要求表中的列不能再有重复的元组。也就是说,表中的每一列都应该包含唯一值,没有重复的组合。它是在第三范式的基础上进一步消除多值依赖的范式。
多值依赖是指一个非主键字段依赖于另一个非主键字段的多个值。在第四范式中,这种多值依赖关系被要求被拆分为独立的关系表,以消除数据冗余和更新异常。
具体来说,如果在一个关系模式中存在多个独立的多值依赖关系,那么这些多值依赖关系应该被分解成单独的关系模式。每个模式都只包含一组相关的数据,从而避免数据的冗余和不一致性。这样的拆分使得数据库结构更加清晰,数据更加简洁,同时也提高了数据的一致性和完整性。
第五范式 - 5NF
它要求表中的每一列都是不可再分的最小单元,并且所有的函数依赖关系都已经被明确地定义。这意味着表中不会有隐含的数据依赖关系,所有的依赖关系都应该清晰地表达出来。这有助于消除所有可能的数据冗余和更新异常。
巴斯-科德范式 - BCNF
BCNF范式并不是传统意义上的第六范式,但实验室同样是数据库设计中重要的一个概念。BCNF要求所有决定因素(即能唯一确定一个元组的属性或属性组)都必须包含候选键。这有助于消除由传递函数依赖导致的冗余和更新异常。
总结
这六大范式在数据库设计中是层层递进的,满足更高层次的范式通常意味着数据库的设计更加合理、数据冗余更少、维护更加方便。但在实际应用中,并不是一定要满足所有范式,而是要根据具体的应用场景和需求进行权衡和选择。