【数据库基础】关系数据库规范化理论之范式

来源:互联网 发布:送礼物的淘宝店铺 编辑:程序博客网 时间:2024/05/18 00:03

因为在写项目时与同伴关于数据库到底建多少张表,每张表应包含哪些属性产生分歧,所以又好好研究了一下关系型数据库在设计时应该遵守怎样的规则以提高数据库性能。

在阅读本篇文章前读者须掌握关系数据库结构基础及函数依赖与键的定义。
可直戳以下目录空降相关知识点↓↓↓

    • 第一范式1NF
    • 第二范式2NF
    • 第三范式3NF
    • BC范式BCNF
    • 多值依赖与第四范式4NF
      • 多值依赖
      • 第四范式4NF
    • 关系模式的规范化步骤
    • 总结

首先要明确关系模型可能存在的异常有:数据冗杂,更新异常,插入异常,删除异常。所有范式存在的意义不过是为了消除这些异常。满足最低要求的一级叫做第一范式(1NF),在第一范式的基础上提出了第二范式(2NF),在第二范式的基础上又提出了第三范式(3NF),以后又提出了BCNF范式,4NF,5NF。范式的等级越高,应满足的约束条件也越严格。规范的每一级别都依赖于它的前一级别。

首先我们给出一张数据表,该表涵盖我们所要记录的所有属性
该关系模式为:
SLC(Sno,Sname,Sdept(所在系),Loca(住处),Cno(课程号),Grade(成绩))

Sno Sname Sdept Loca Cno Grade 03001 甲 网络工程 A C1 95 03001 甲 网络工程 A C2 88 04001 乙 计算机科学与技术 B C2 93 04001 乙 计算机科学与技术 B C4 75 03002 丙 网络工程 A C1 77 02001 丁 网络工程 A C5 82 02002 戊 计算机科学与技术 B C2 87

第一范式(1NF)

如果关系模式R中的所有属性都是不可分的数据项,则称R属于第一范式,记为R∈1NF。

对数据表进行分析,可知其每个属性都不可再分,既满足1NF,但由于只有属性Grade对键(Sno,Cno)是完全函数依赖,而其他非主属性都是对键的部分函数依赖,也正是因为关系中存在部分函数依赖,导致数据操作中必然会存在异常,故需要运用投影运算将关系模式SLC进行分解,转向更高一级范式。

第二范式(2NF)

若关系模式R∈1NF,且每个非主属性都完全依赖于R的键,则R∈2NF。

关系SLC中,Sno、Cno为主属性,Sname,Sdept,Loca,Grade均为非主属性,Grade对键是完全函数依赖,其余非主属性对键均为部分函数依赖,所以SLC∉2NF。
为消除关系模式SLC中的部分函数依赖,我们采用投影分解法,将部分函数依赖从SLC中分解出来,得到以下两个关系模式:
SC:(Sno,Cno)->[f]Grade
SL:(Sno->[f]Sname, Sno->[f]Sdept, Sno->[f]Loca)
分解后关系模式SC和SL的非主属性对键都是完全函数依赖,所以SC∈2NF,SL∈2NF。

满足2NF后我们再分析对数据进行操作时可能出现的异常问题是否得到有效解决:
①插入异常:
【已解决】若学生未选课,仍能将相关信息插入表SL中。
【未解决】若某系还未进行招生,即Sno为空时,该系相关信息无法插入。
②删除异常:
【已解决】即使删除SC表中某个学生的全部选课信息,但表SL中仍有其其余信息存在。
【未解决】若某系所有学生毕业,删除全部学生信息的同时,该系的相关信息也被删除了。
③更新异常:
【已解决】因为学生的选课信息与基本信息分别存储在两张表中,基本信息在SL表中只保存了一次,所以当学生的基本信息(如姓名)产生变化时,Sname的值只需要修改一次,减少了数据冗杂。
【未解决】若某系改名,则要对每个学生记录中的Sdept进行修改。
④数据冗杂
【未解决】一个系中有多个学生,对每个学生记录,相关的Sdept和Loca都要储存一次。

因此SL仍不是一个好的关系模式,需要对其进行进一步分解,转化为更高一级的范式。

第三范式(3NF)

对于关系模式R,每一个非主属性键既不部分函数依赖于键,也不传递函数依赖于键,则R∈3NF。

关系模式SC中非主属性Grade既不部分函数依赖于键,也不传递函数依赖于键,所以SC∈3NF,但在关系模式SL中,由于Sno->Sdept, Sdept->Loca, Sdept-(×)>Sno,所以Sno->[t]Loca,所以SL∉3NF。因此仍要对SL进行投影分解,得到以下两个关系模式
S(Sno,Sname,Sdept)
L(Sdept,Loca)
现在关系模式S和L中既不存在部分函数依赖,也不存在传递函数依赖,所以S∈3NF,L∈3NF。

通常情况下,数据库的设计满足3NF即已达到标准,此时所有异常问题都能得到解决,但由于3NF只是规定了非主属性对键的依赖关系,没有限制主属性对键的依赖关系,若存在主属性对键的部分函数依赖和传递函数依赖关系,同样会出现数据冗杂,插入异常,更新异常,删除异常等问题,因此我们引入BC范式。

BC范式(BCNF)

关系模式R∈1NF,若X->Y,且Y∉X时X必为键(),则R属于BCNF。即在关系模式R中,若每一个决定因素都为键,则R一定属于BCNF。

对于满足BCNF的关系模式,具有以下性质:
①所有非主属性都完全函数依赖于每个候选键。
②所有主属性都完全函数依赖于每个不包含它的键。
③没有任何属性完全函数依赖于非键的任何一组属性。

简单来说,相比3NF,BCNF更为严格的一点就是要求R的每一个属性都不部分函数依赖于候选键且不传递函数依赖于候选键
若R∈BCNF则R一定∈3NF,但反之不一定成立。

例如对关系模式S(Sno,Sname,Sdept),S∈3NF,同时S中Sno是唯一的决定性因素,因此S∈BCNF。

再例如,有一个关系模式City(Cname,Street,Code),其中Cname表示城市名,Street表示街道名,Code表示街道所在地区的邮政编码,其上所具有的函数依赖关系为:
(Cname,Street)->Code, Code->Cname
候选键为(Cname,Street)和(Code,Street),不存在非主属性,故City∈3NF,但决定因素Code不是键,所以City∉BCNF。

再举一例,有一个关系模式STJ(S,T,J),其中S表示学生,T表示教师,J表示课程,每个教师只讲授一门课程,每门课程可由多个教师讲授,某一学生选定某门课程,就对应一个确定的教师,因此可得如下函数依赖:
(S,J)->T,(S,T)->J,T->J
(S,J)和(S,T)都是候选键,所以该关系中的S、T、J均为主属性,不存在非主属性键,也就不存在非主属性对键的部分函数依赖和传递函数依赖,STJ∈3NF,但STJ∉BCNF,因为在T->J中,T是决定因素,但T不是键。

对于关系模式STJ,我们可举一条实例分析不是BCNF的关系模式将会存在怎样的异常问题

学生S 教师T 课程J 甲 教授A 大学语文 乙 教授A 大学语文 丙 教授B 大学语文 丁 教授B 大学语文 乙 教授C 大学英语 乙 教授D 大学英语 乙 教授E C语言

数据冗杂:每个教师只讲授一门课程,但选修了该门课程的多个学生记录中都要存储教师信息。
插入异常:若学生还没有选课,则教师及课程的信息无法录入,因为主属性此时为空。
更新异常:当课程改名后,所有选修了该课程的学生纪录需要逐条修改属性J的值,容易造成数据的不一致,破坏数据库完整性。
删除异常:若选修了某门课程的所有学生毕业,在删除所有学生信息的同时,有关课程的信息也被删除了。
因此,将该关系模式分解为以下两个关系模式:ST(S,T)和TJ(T,J),他们间存在的函数依赖为S->T,T->J
此时关系模式ST和TJ均达到BCNF,从而解决上述提到的异常。

一个关系模式如果达到了BCNF,那么在函数依赖范畴内,它就已经实现了彻底的分离,消除数据操作中可能出现的异常。

多值依赖与第四范式(4NF)

①多值依赖

在关系模式中,函数依赖不能表示属性值之间的一对多联系,这些属性之间有些虽然没有直接关系,但存在间接的关系,把没有直接联系、但有间接的联系称为多值依赖的数据依赖。
简单来说,在函数依赖中,X与Y是否存在函数依赖关系,只需考察X,Y的两组属性,与别的属性无关。而在多值依赖中,X与Y是否存在多值依赖还需看属性Z。
数学定义: 设R(U)是一个属性集合U上的一个关系模式,X, Y, 和Z是U的子集,并且Z=U-X-Y,多值依赖X->->Y成立当且仅当对R的任一个关系r,r在(X,Z)上的每个值对应一组Y的值,这组值仅仅决定于X值而与Z值无关。
平凡的多值依赖与非平凡的多值依赖:
若X->->Y,而Z为空集,则称X->->Y为平凡的多值依赖;若Z不为空,则称其为非平凡的多值依赖。
多值依赖的缺点在于数据冗杂太大。

举例:有这样一个关系 <仓库管理员,仓库号,库存产品号> ,假设一个产品只能放到一个仓库中,但是一个仓库可以有若干管理员,那么对应于一个 <仓库管理员,库存产品>有一个仓库号,而实际上,这个仓库号只与库存产品号有关,与管理员无关,就说这是多值依赖。

多值依赖具有以下性质:
①对称性:若X->->Y,则X->->Z,其中Z=U-X-Y
②传递性:若X->->Y,Y->->Z,则X->->Z-Y
③合并性:若X->->Y,X->->Z,则X->->YZ
④分解性:若X->->Y,X->->Z,则X->->(Y∩Z),X->->Z-Y,X->->Y-Z均成立,也就是说两个相交的属性子集均多值依赖于另一个属性子集,则这两个属性子集因相交而分割成的3部分也都多值依赖于该属性子集。
⑤函数依赖可以看作是多值依赖的特例。若X->Y,则X->->Y,因为,当X->Y时,对X的每一个取值x,Y有一个确定的值y与之相对应,所以X->->Y。

那么若想上例中的关系模式消除多值依赖,作模式分解,使子模式的Z=Ø,仅有平凡多值依赖,即子模式为R1(仓库号,仓库管理员),R2(仓库号,库存产品号)

②第四范式4NF

在多值依赖的基础上我们引入第四范式的概念

设关系R(X,Y,Z),其中X,Y,Z是成对的、不相交属性的集合。若存在非平凡多值依赖,则意味着对R中的每个属性Ai(i=1,2…n)存在有函数依赖 X->Ai(X必包含键)。那么R∈4NF。
第四范式限制关系模式的属性之间不允许出现非平凡且非函数依赖的多值依赖。因为对于每一个非平凡的多值依赖X->->Y,X都含有键,所以X->Y,故4NF所允许的非平凡的多值依赖实际上就是函数依赖。
若关系属于4NF,则它必属于BCNF;而属于BCNF的关系不一定属于4NF

在上述关系模式 <仓库管理员,仓库号,库存产品号>中,键是(仓库管理员,仓库号,库存产品号),仓库号->->仓库管理员,仓库号->->库存产品号,但仓库号并不是一个键,因此该关系不是4NF,而分解成R1(仓库号,仓库管理员),R2(仓库号,库存产品号)后,虽然仍存在仓库号->->仓库管理员,仓库号->->库存产品号,但他们是平凡的多值依赖,所以R1∈4NF,R2∈4NF。

如果只考虑函数依赖,则BCNF的关系模式规范程度已经达到最高
如果考虑多值依赖,那么4NF的关系模式规范化程度最高
另外还有其他数据依赖如连接依赖,多值依赖是连接依赖的一种特殊情况。在消除4NF关系模式中存在的连接依赖后则可进一步达到5NF,这里不再赘述。

关系模式的规范化步骤

(1)取原始的1NF关系投影,消去非主属性对键的部分函数依赖,从而产生一组2NF关系。
(2)取2NF关系的投影,消去非主属性对键的传递函数依赖,产生一组3NF关系。
(3)取这些3NF的投影,消去决定因素不是键的函数依赖。产生一组BCNF关系。
(4)取这些BCNF关系的投影,消去其中不是函数依赖的非平多值依赖,产生一组4NF关系。

总结

规范化程度越高,分解就越细,所得关系的数据冗杂就越小,异常情况也就越少,但同时也增大了系统对数据检索的开销,降低了数据检索的效率。系统只有对这些细分的关系进行自然连接,才能获取所需的信息,而连接操作所需的系统资源和开销是比较大的,因此,规范化程度越高的关系模式并非是最好的。
规范化应满足的基本原则是由低到高,逐步规范,权衡利弊,适可而止。通常以满足第三范式为基本要求。

参考文献:孟彩霞. 数据库系统原理与应用[M]. 人民邮电出版社: 2008.