数据库入门(一)范式理解:1NF,2NF,3NF,BCNF,4NF详析
引言
Normal Form范式是“符合某一种级别的关系模式的集合,表示一个关系内部各属性之间的联系的合理化程度”。一脸懵逼的我们如何理解这句话呢,简单地说可以把他理解为一张数据表的表结构所符合的设计标准级别,像英语的四六级,相对代表了英语水平的高低。
满足这些规范的数据库是简洁的,结构明晰的,同时不会发生插入(insert),删除(delete)和更新(update)操作的异常
范式种类
数据库范式分为1NF,2NF,3NF,BCNF,4NF,5NF。一般在我们设计关系型数据库的时候,最多考虑到BCNF就够。符合高一级范式的设计,必定符合低一级范式
第一范式(1NF)
符合1NF的关系中的每个属性都不可再分
- 在使用数据库管理系统的时候比如mysql,sqlserver等数据表都必须满足第一范式。
- 属性不可再分的意思是每一个字段都是最小的,不包含其他字段,不重复,原子性。
存在问题
如上例,第一范式的不全面性造成了许多问题。
- 数据冗余:如学号、姓名、系名、系主任这些数据重复多次。
- 插入异常:如学校新建了一个系,但是暂未招生学生无法将系插入表内(缺少主键)。
- 删除异常:如将某个系中所有学生相关的记录都删除,那么所有系与系主任的数据也就随之消失了。
第二范式(2NF)
在1NF基础上消除了非主属性对码的部分函数依赖
- 码(候选码):一个表里面,可以惟一决定一个元组属性的集合。
主属性:码里面的属性。
非主属性:不是码里面的属性。 - 函数依赖:若在一张表中,在属性(或属性组)
的值确定的情况下,必定能确定属性
的值,那么就可以说
函数依赖于
,写作
。
- 完全函数依赖:在一张表中,若
,且对于 X 的任何一个真子集(假如属性组
包含超过一个属性的话)
不成立,那么我们称
对于
完全函数依赖,记作
,如:
- 部分函数依赖:假如
函数依赖于
,但同时
并不完全函数依赖于
,那么我们就称
部分函数依赖于
,记作
,如:
二范式判断步骤
- 找出数据表中所有的码
- 找出主属性和非主属性
- 查看是否存在非主属性对码的部分函数依赖。
- 将表拆分使每一个非主属性都完全函数依赖于候选码
优缺点
优:
- 减少数据冗余
- 修改异常解决。
缺: - 插入异常
- 删除异常
第三范式(3NF)
在2NF基础上消除非主属性对码的传递函数依赖
- 传递函数依赖:设 是关系 中互不相同的属性集合,存在 则称 传递函数依赖于 。
对于原学生表,主码为学号,主属性为学号,非主属性为姓名、系名和系主任。因为 学号 → 系名,同时系名 → 系主任,所以存在非主属性系主任对于码学号的传递函数依赖,所以学生表的设计,继续拆分修改使其满足3NF的要求:
优缺点
- 优点
基本上解决了数据冗余过大,插入异常,修改异常,删除异常的问题,作为数据库设计人员,至少应该知道,3NF的要求是怎样的。 - 缺点
查询耗时间,可能要查好几张表。
BCNF范式(3NF的改进形式)
BCNF条件
1.所有非主属性对每一个码都是完全函数依赖。
2.所有的主属性对每一个不包含它的码,也是完全函数依赖。
3.没有任何属性完全函数依赖于非码的任何一组属性。
为什么引入BCNF
下面看看这样一个问题,假设仓库管理关系表(仓库号,存储物品号,管理员号,数量),满足一个管理员只在一个仓库工作;一个仓库可以存储多种物品,则存在如下关系:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cXEIosGc-1586086591678)(]#pic_center)
(仓库号,存储物品号)和(管理员号,存储物品号)都是仓库管理关系表的候选码,表中唯一非关键字段为数量,此关系模式已经属于了 3NF,那么这个关系模式是否存在问题呢?我们来看以下几种操作:
- 插入异常:新增加一个仓库,但尚未存放任何物品,无法为该仓库指派管理员——物品名也是主属性,根据实体完整性的要求,主属性不能为空。
- 删除异常:某仓库被清空后,需要删除所有与这个仓库相关的物品存放记录——仓库本身与管理员的信息也被随之删除。
- 更新异常:如果某仓库更换了管理员,这个仓库有几条物品存放记录,就要修改多少次管理员信息。
解决方法
我们可以得出结论,在某些特殊情况下,即使关系模式符合 3NF 的要求,仍然存在着插入异常,修改异常与删除异常的问题,仍然不是 ”好“ 的设计。这是由于存在如下决定关系:
即关键字段决定关键字段的情况。把仓库管理关系表分解为两个关系表仓库管理表(仓库号,管理员号)和仓库表(仓库号,存储物品号,数量),这样这个数据库表是符合BCNF的,并消除了删除异常、插入异常和更新异常。
第四范式(4NF)
限制关系模式的属性之间不允许有非平凡且非函数依赖的多值依赖。下面介绍几个概念:
相关概念介绍
多值依赖
-
多值依赖定义:
设R(U)是一个属性集U上的一个关系模式, X、 Y和Z是U的子集,并且Z=U-X-Y。关系模式R(U)中多值依赖 X→→Y成立,当且仅当对R(U)的任一关系r,给定的一对(x,z)值,有一组Y的值,这组值仅仅决定于x值而与z值无关,如下,任意调换 , 皆满足
-
判定方法:
对于任意关系中,如果存在两个元组(就是行),记为A,B,如果他们的某一属性X的值相等,那么我们交换它们另外的属性Y的值后,得到的新的两个元组,在表中是可以在原来的表中找到与它们相匹配的元组的。
如:
我们可以找到第一和第四行,它们的属性X=物理是相同的,当我们交换Y=教员属性后得到(物理,王军,普通物理学)和(物理,李勇,普通物理学),与原来的表相比,是一毛一样的。我们也可以交换第三行和第四行,得到(物理,王军,物理习题集)和(物理,李勇,普通物理学),与原来表相比,我们还是能找到与它们相匹配的元组的。
Teaching模式中存在的问题
Teach具有唯一候选码(C,T,B), 即全码
(1)数据冗余度大:有多少名任课教师,参考书就要存储多少次
(2)插入操作复杂:当某一课程增加一名任课教师时,该课程有多少本参照书,就必须插入多少个元组
(3) 删除操作复杂:某一门课要去掉一本参考书,该课程有多少名教师,就必须删除多少个元组
(4) 修改操作复杂:某一门课要修改一本参考书,该课程有多少名教师,就必须修改多少个元组
产生原因: 存在多值依赖
平凡函数依赖和非平凡的函数依赖
平凡函数依赖:当关系中属性集合Y是属性集合X的子集时(YX),存在函数依赖X→Y,即一组属性函数决定它的所有子集,这种函数依赖。
多值依赖与函数依赖的区别
1)若函数依赖X→Y在R(U)上成立,则对于任何Y’ 属于Y均有X→Y’ 成立(一对一)。
2)多值依赖X→→Y若在R(U)上成立,不能断言对于任何Y’ 属于Y有X→→Y’ 成立,因为多值依赖中,其实就是一对一组,一个老师可能教多门课,不同老师可能有教相同的课,所以不能推出X→→Y’ 成立。
3)把一组改为一个,实际上就是函数依赖,所以说函数依赖是多值依赖的特例,多值依赖不一定是函数依赖,但函数依赖一定是多值依赖。
了解4NF
1)消除非平凡且非函数依赖的多值依赖
2)函数依赖是4NF
3)平凡的多值依赖是4NF
Point
- 4NF所允许的非平凡多值依赖实际上是函数依赖。
- 当一个表中的非主属性互相独立时(3NF),这些非主属性不应该有多值
总结
-
一范式:原子性。
-
二范式:非主属性不存在部分函数依赖。
-
三范式:非主属性不存在传递函数依赖。
-
BCNF范式:主属性对不包含它的码,不存在部分函数依赖。
-
四范式:不允许有非平凡且非函数依赖的多值依赖
-
更多学习链接(可以康康的资料):
六大范式详解
数据库中的范式和多值依赖