第六章 关系数据理论 范式
这一章的重点放在范式,主要内容如下:
何为范式 ?
范式是“符合某一种级别的关系模式的集合,表示一个关系内部各属性之间的联系的合理化程度”。说白了就是一张数据表的表结构所符合的某种设计标准的级别。范式级别越高,表的设计就越标准。
第一范式(1NF)
第一方式是数据库表需要符合的最基本条件:表的每一个属性不能是再可分的数据项。
如一张表是这样的:
其中属性进货还可以再分,所以这张表的设计不符合第一范式。
改为:
就符合了第一范式的要求了。
仅仅符合第一范式的表还是有很多问题的,如下数据表:
每一名学生的学号、姓名、系名、系主任这些数据重复多次。每个系与对应的系主任的数据也重复多次——数据冗余过大。
假如学校新建了一个系,但是暂时还没有招收任何学生(比如3月份就新建了,但要等到8月份才招生),那么是无法将系名与系主任的数据单独地添加到数据表中去的 ——插入异常
假如将某个系中所有学生相关的记录都删除,那么所有系与系主任的数据也就随之消失了(一个系所有学生都没有了,并不表示这个系就没有了)。——删除异常。
假如李小明转系到法律系,那么为了保证数据库中数据的一致性,需要修改三条记录中系与系主任的数据。——修改异常。
正因为仅符合1NF的数据库设计存在着这样那样的问题,我们需要提高设计标准,去掉导致上述四种问题的因素,使其符合更高一级的范式(2NF),这就是所谓的“规范化”。
关于第二范式的一些先修概念
函数依赖:若在一张表中,在属性(或属性组)X的值确定的情况下,必定能确定属性Y的值,那么就可以说Y函数依赖于X,写作 X → Y。
如有一张学生表Student(sno,sname , sage) , 学号sno确定的情况下,姓名sname可以唯一确定,所以可以有 学号->姓名。但是“姓名->学号“是不成立的,因为学生可能同名。
对于Student表,还可以有“学号sno->年龄sage“。
完全函数依赖:在一张表中,若 X → Y,且对于 X 的任何一个真子集(假如属性组 X 包含超过一个属性的话)X1,X1 → Y 不成立,那么我们称 Y 对于 X 完全函数依赖。
对于上面的Student表,可以说姓名sname完全依赖于学号sno:”sno->sname”。
部分函数依赖:在一张表中,若X -> Y , 存在一个X的真子集X1,使得X1->Y,那么就可以说Y部分依赖于X。
如有选课的表sc(sno,cno , grade) 。(sno , cno) 可以确定 grade , 记做(sno , cno)->grade 。但同时也存在着sno->grade,所以可以说grade部分依赖于(sno , cno)。
传递函数依赖:若Y->Z , X->Y, 那么有X->Z (Z 依赖于 X ) 。
如一个student表 ,student(sno,deptNo , deptName)。学号sno->系号deptno , 系号deptNo -> 系名称deptName , 那么有sno -> deptName 。
码:若一个表中的属性集合K能够确定表中的所有其他属性 , 那么称K为关系表的码。关系表的码可能不止一个。包含于码中的任一属性叫主属性,不包含与码中的属性叫非主属性。
如上面说的选修表sc(sno , cno , grade) , (sno , cno )就是sc的一个码 , grade是非主属性 , sno 、cno可以叫表的主属性。
第二范式(2NF)
终于可以回过来说第二范式了。
第二范式就是在第一范式的基础之上消除了非主属性对码的部分依赖 。
如有关系模式R(sno,dept,sloc,cno , grade)。sno学号,dept为系,sloc为住处,cno课程号,grade成绩。关系R的码为(sno,cno), 存在这样的函数依赖:
(sno,cno)->grade
sno->dept , (sno,cno)->dept
sno->sloc , (sno,cno)->sloc
dept->sloc(一个系只有一个住处)
由(sno,cno)->dept , sno->sdept可知存在部分依赖,同理sloc部分依赖于(sno,cno)。这个关系模式R不属于第二范式2NF。
第二范式仍然存在以下问题:
插入异常:若要插入一个学生,sno = 18 , dept=’计算机’ , sloc=’35栋’ ,但是由于该学生的课还没选好,这样整个的一条学生的记录都无法插入。
删除异常:若一个学生选修了一门课C3 , 现在这门课他不选了, 那么这条记录都要删除掉,把学生的其他不该删除的信息也删除了。
修改复杂:若一个学生转系了,本来只要修改dept即可,但是在这张表里还有修改sloc(住处),若学生修改了多门课程,那么多条记录都要发生修改,就造成了修改复杂。
可以看出符合2NF的表设计也还有很多问题的。
第三范式 3NF
第三范式就是在第二范式的基础上再消除了非主属性对码的传递依赖。
有关系R(sno , sdept , deptName) 。sno->sdept , sdept->deptName 。
码:sno
非主属性:sdept , deptName。
由sno->sdept , sdept->deotName得:sno->deptName 。
存在传递依赖 ,不符合3NF。
分解关系R为:R1(sno , sdept)和 R2(sdept , deptName) ,分解后的关系就符合了3NF 。
修正的第三范式 BCNF
BCNF就是在第三范式的基础上消除了主属性对码的部分依赖和传递依赖。
存在关系模式STJ(S , T , J),S是学生,T是教师 , J是课程。一个老师只带一门课 , 一门课有多个老师可以上,一个学生只有一个固定的老师。
那么有如下关系:
(S , J )->T , (S , T)->J , T->J
这里(S , J)和(S , T)都是候选码。
码:S , T ,J 。
非主属性:无。
可以看出关系STJ各项不可再分(符合1NF),没有非主属性 (符合2NF和3NF)。
由(S , T)->J , T->J知主属性对码(S,T)存在部分依赖所以关系STJ不符合BCNF 。
可以通过分解STJ为 R1(S,T) , R2(T,J),此时R1、R2都符合BCNF。
各范式的关系
再看第一张图
参考:
1、 知乎高赞回答:https://www.zhihu.com/question/24696366
2、 数据库系统概论 第五版。