乐趣区

技本功丨解析范式(1NF-4NF),科普得如此直白易懂,别拦着我要学习~

亲爱的盆友们~ 又是新的一年,你,准备好新的学习计划了吗~?是读书 100 本,还是考上 5 个证?嘛~ 不管怎么说,角落里那一堆蒙尘的计划表好像在昭示着这仍然是一个充满朝气又艰难的 9102 年呢!总之,先把 #技本功# 进修班报了再说吧~ 何以暴富,唯有学习!

-2019 年第 3 期 -

夫子说
数据库的库表设计是数据库开发阶段的基础,合理的结构和关系将会大大提升以后数据库的运行性能;而表设计要遵循范式规则,除了比较常见和通用的三大范式外,还有 BCNF、4NF、5NF… 甚至更高的范式,但是也不是范式越高越好,有时候也需要逆范式化设计表。今天,就重点讲一讲解析范式(1NF-4NF)。
1NF  
1、1NF 的定义
关系数据库中的关系是要满足一定要求的,满足不同程度要求的为不同的范式。满足最低要求是第一范式(1NF),1NF 的定义如下:1NF:关系中的每一个分量必须是一个不可分的数据项。通俗地说,第一范式就是表中不允许有小表的存在。比如,对于如下的员工表,就不属于第一范式:

上表中,出现了属性薪资又被分为基本工资和补贴两个子属性,就好像表中又分割了一个小表,这就不属于第一范式。如果将基本工资和补贴合并,那么该表符合 1NF。
2、1NF 存在的问题
1NF 是最低一级的范式,范式程度不高,存在很多的问题。比如用一个单一的关系模式学生来描述学校的教务系统:
学生(学号, 学生姓名, 所在系, 系主任姓名, 课程号, 成绩)
学生表

假如选定学号为主键,这个表满足第一范式,但是存在如下问题:
● 数据冗余:一个系有很多的学生,同一个系的学生的系主任是相同的,所以系主任名会重复出现。● 更新复杂:当一个系换了一个系主任后,对应的这个表必须修改与该系学生有关的每个元组。● 插入异常:如果一个系刚成立,没有任何学生,那么这个无法把这个系的信息插入表中。● 删除异常:如果一个系的学生都毕业了,那么在删除该系学生信息时,这个系的信息也丢了。
2NF  
1、2NF 的定义
2NF 的定义:如果关系 R 属于 1NF,且每一个非主属性完全函数依赖于任何一个候选码,则 R 属于 2NF。
通俗地说,2NF 就是在 1NF 的基础上,表中的每一个非主属性不会依赖复合主键中的某一个列。
按照定义,上面的学生表就不满足 2NF,因为学号不能完全确定课程号和成绩(每个学生可以选多门课)。将学生表分解为:学生(学号, 学生姓名, 系编号),系(系编号, 系名, 系主任),选课(学号, 课程号, 成绩)。每张表均属于 2NF。
新定义一张表:销售表(产品 id, 地区 id, 价格, 产品名),同一个产品在不同地区价格不同。这个表就不属于 2NF,因为非主属性产品名不是完全函数依赖于主键,而是完全依赖于产品 id,即表中存在非主属性对主键的部分依赖。将销售表分解:产品(产品 id, 产品名),销售表(产品 id, 地区 id, 价格)。每张表均属于 2NF。
2、2NF 存在的问题
下面举例说明 2NF 存在的相应问题。
对于公司里的员工管理,每个员工只能属于一个部门,每个部门可以有多个员工,定义如下关系模式:
员工管理表(员工 id, 员工名, 所属部门 id, 部门经理);
对应的表:

在的问题:● 删除异常:如果某个部门的人都跳槽了,那么在删除这些员工的同时也丢失了这个部门的信息。● 修改复杂:如果一个员工换了一个部门,不但要修改所属部门,还要修改部门经理这个属性列。● 插入异常:如果公司新成立了一个部门,但是目前没有招收员工,那么这个部门信息也无法插入到这个表中,因为没有主键。
3NF  
1、3NF 的定义
3NF 的严格定义如下:
关系模式 R 属于 1NF,若 R 中不存在这样的码 X,属性组 Y 及非主属性 Z,使得 X 函数确定 Y、Y 函数确定 Z 成立,Y 不能函数确定 X,则称 R 是属于 3 范式的。
通俗地说,就是在满足 1NF 的基础上,表中不存在非主属性对码的传递依赖。也就是说表中非主属性不会间接地依赖于码。
如上面的员工管理表就不属于 3NF,因为非主属性部门经理依赖于所属部门,所属部门依赖于员工 id,即部门经理传递依赖于员工 id。将员工管理表分解:员工管理(员工 id, 员工名, 部门名),部门(部门名, 部门经理)。则每张表均属于 3NF。
2、3NF 存在的问题
现在有这样的一个场景:对于一个工程 (ENO) 的实施,每个工程需要多个零件,每个供应商 (SNO) 只生产一个零件 (PNO) 且受工厂规模所限只能同时供应一个工程,每个工程使用的同一个零件都来自同一个生产商。
定义关系模式:SPE(SNO,PNO,ENO)。

表中存在如下函数依赖:(ENO,PNO)→SNO(ENO,SNO)→PNOSNO→PNOSPE 是属于 3NF 的,因为根据定义,表中不存在非主属性对码的传递依赖和部分依赖。但是这张表存在如下的问题:● 插入异常:如果有一个新的工厂建立了,但是这家工厂还没有接到任何订单,那么无法将这个工厂信息插入到 SPE 中,因为缺少了主属性 ENO。● 删除异常:如果某个供应商只给一个工程提供零件,现在这个工程不再需要这个零件了。那么 PNO 就要删除,而 PNO 是主属性,整个元组都被删除了,这样就丢失了一个供应商信息。
BCNF  
1、BCNF 的定义
BCNF 比 3NF 更进一步,可以认为是扩充的 3NF,其定义如下:
关系模式 R 属于 1NF,若 X 函数确定 Y(且 X 不包含 Y)时 X 必含有码,则 R 属于 BCNF。
翻译成人话,就是在第一范式的基础上,若关系 R 中的每一个决定因素都必含有码,则关系 R 属于 BCNF。
很显然,上面的 SPE 表不属于 BCNF,因为 SPE 中存在一个决定因素 SNO,SNO 不含有码。将 SPE 表分解:SP(SNO,PNO),SE(SNO,ENO)。则每张表均属于 BCNF。
2、BCNF 存在的问题
仍以上面的工程实施场景为例:假设每个供应商可以生产多个零件,可以供应给多个工程,一个工程需要多个零件,但同一个工程的同一个零件必须来自同一个供应商。
那么关系 SPE(SNO,PNO,ENO)对应的表数据可能是如下:

此时表 SPE 存在如下的函数依赖:(PNO,ENO)→SNO
根据 BCNF 的定义,此时表 SPE 属于 BCNF。但是这样的关系模式仍具有不好的地方:数据冗余度太大。假如供应商 S3 生产了 n 个零件,每个零件供应给 m 个工程,那么显然 S3 要在表中重复 m * n 次。
4NF  
1、4NF 的定义
4NF 严格定义如下:关系模式 R 属于 1NF,对于 R 中的每一个非平凡多值依赖 X→→Y(X 不包含 Y),X 都含有码,则 R 属于 4NF。
通俗地说,对于有三个属性的表,给定属性 A 一个值,剩余两个列之间不存在多对多的关系。例如,在上面的 SPE 表中,给定 SNO=S1,PNO 和 ENO 之间很明显存在多对多的关系,故上表是不属于 4NF 的。
根据 4NF 的定义可知,4NF 所允许的非平凡的多值依赖实际上就是函数依赖,4NF 就是消除表中的非平凡多值依赖关系。
2、4NF 存在的问题
一般地,4NF 属于规范程度比较高的范式了。但是考虑到连接依赖的话,4NF 中也仍存在数据冗余,插入、修改、删除异常等问题。如果消除了 4NF 中的连接依赖,则达到了 5NF 的关系模式;5NF 范式化已经很高了,实际工作中很少会遇到这么高的范式表,这里就不再叙述了。
范式的相关总结
如果只考虑函数依赖,那么 BCNF 范式最彻底,已消除插入和删除的异常。而 3NF 的不彻底性表现在表中可能存在主属性对码的部分依赖和传递依赖。
如果考虑到多值依赖,那么 4NF 范式是规范程度最高的。但 4NF 中可能存在连接依赖的关系,而 5NF 可以消除连接依赖。
在数据库中,有时并不是规范化程度越高越好,有时候也需要逆范式化设计表。因为范式越高,产生的表就越多,一个简单的查询需求就可能涉及到多张表的关联,影响查询效率。一般地,数据库中的表都在 3NF。

退出移动版