一文读懂1范式(1NF)、2范式(2NF)、3范式(3NF)
范式的基本概念
范式可以理解为是一种模式或规范,在我们设计关系型数据库的时候,常常会用到,要求表满足这种规范。
三种范式之间的关系:在 1NF 的基础上增加一些条件,达到2NF要求,在2NF基础上满足一些要求,到达3NF要求,及三种范式之间有一种包含关系,1NF 包含于 2NF,2NF包含于3NF。当然范式不止这三种,还有BCNF、4NF、5NF。
1、什么是1NF
1NF要求二维表格中每一列的原子性,所为原子性,也就是不可再拆分,也是一个最基本的条件。
列的原子性:如下表,我们通过实例来说明
姓名 | 班级 |
---|---|
张三 | 一年级二班 |
上表中年纪这一列,就不具备原子性,所以不满足1NF,这一列可以拆分为年级和班级两列。
再例如,我们在填个人信息表格的时候,会经常看到填电话号码,电话号码可以差分为手机号码,和座机号码两列。
2、什么是2NF
在满足1NF的基础上,没有非主属性对码(可以理解为主键)的部分函数依赖。也就是全部都是完全函数依赖,部分函数依赖通常是因为有两个主属性。
2.1、怎么确定码(主键)
在一张表中,我们要确定码,那么必定能通过这个码来推到出其他属性。
假如有学生表(学号,姓名,年纪,班级,班主任),来让我们来确认码,分析表中的各个属性,我们知道每个学生的学号肯定是唯一的(注:码如果是一个,那么必定是唯一的,不能有相同值,如果是多个,允许有相同,当不允许多个码都相同),那么我们可以通过学号可以推导出其他所有属性的值,即这张表中的码为 学号。
另一张学生表选课表(学号,课程号,成绩),先通过学号,发现直接通过学号不能得到成绩,因为一个学生可能选择多个课程,而(学号,课程号)可以得到成绩,即这张表中的码为(学号,课程号)。
举个栗子:
一张学生成绩表中有属性(学号,姓名,科目,成绩,年纪,班级,班主任)
这个表中有两个主属性为(学号、科目),其他的属性都为非主属性,函数依赖的意思就是说,通过主属性可以推断出非主属性,例如通过(学号,科目)--------->(成绩)等,这种叫做完全还是依赖;部分函数依赖则就是通过部分主属性,也可以推断出其他非主属性,如(学号)----->(姓名);所以学生成绩表是不满足2NF的。
3、什么是3NF
在满足2NF的基础上,不存在非主属性对码的传递函数依赖。
传递函数依赖,A依赖B,B依赖C,则可以得到A依赖C。纵使通过A可以直接得到C,但如果存在A依赖B,B依赖C这种关系,也不满足3NF的要求。
例如:学生表(学号,姓名,年纪,班级,班主任)
此表中学号为主键(码),通过学号可以推导出其他属性值。但在其中存在传递函数依赖,学号—>班级,班级–>班主任,这是一种传递函数依赖,所以不满足3NF条件。
总结:当不满足范式要求的时候,有时候就需要通过拆表来使每个表都满足要求,例如学生表(学号,姓名,年纪,班级,班主任)是不满足3NF的,那么我们将此表拆分为两个表;学生表(学号,姓名,年纪,班级),班级表(班级,班主任);这样两个表就都满足3NF了。