目录
范式可以理解为表的结构所符合的某种设计标准的级别。
(1)1NF
属性具有原子性,不可分。
符合1NF的设计仍然存在一些问题:
①数据冗余
姓名系名系主任多次出现。
②增删异常
新建一个系没有学生无法插入,同样删除某个系的所有学生,和这个系相关的信息也没了。
(2)2NF
表中不允许存在非主属性(非主属性:不包含在任何候选码中的属性称为非主属性或非码属性。)对码的(主码或候选码都简称为码)部分依赖。
学号,姓名都能唯一标识(假设姓名唯一),都是主属性,年龄性别都是非主属性。
函数依赖:X依赖Y,则Y确定X也会确定,如学号确定,姓名也会确定。
完全依赖:(学号,姓名)->年龄,年龄部分依赖于(学号,姓名),学号或姓名就能决定年龄。
(学号,课程号)->成绩,成绩完全依赖于学号和课程,只有学号和课程号都确定了,才能知道这门课的成绩。
不满足2NF的例子
首先分析出(学号,课名)是码(唯一候选码),只有这两个属性确定了,其他属性才能确定,【姓名、系名、系主任、分数】是非主属性。
学号确定了姓名也就确定了,所以这个表存在非主属性(姓名)对码(学号,课名)的部分依赖。
解决方法(模式分解):
选课(学号,课名,分数)
学生(学号,姓名,系名,系主任)
(3)3NF
3NF在2NF的基础上:消除了非主属性对于码的传递函数依赖。
传递依赖
学号-->系名-->系主任,(此时不能插入没有学生的系,当一个系的学生都毕业了,该系的信息也会消失)。
解决方法:分解
选课(学号,课名,分数)
学生(学号,姓名,系名)
院系(系名,系主任)
基本上解决了数据冗余过大,增删改异常的问题。当然,在实际中,往往为了性能上或者应对扩展的需要,经常 做到2NF或者1NF。
(4)属性集闭包
闭包能判断该属性集是不是超码,也就是该属性集和依赖集在Armstrong公理下能不能推出整个属性集。
例1: 设有关系模式R(U,F),其中U={A,B,C,D,E},F={ AB → C,B → D,C → E,CE → B,AC → B},计算(AB)+。
解: 由上述算法得:
第一次: ① X(0)= Ф,X(1)=AB;
②由于X(0)≠ AB,置X(0)=AB;
③搜索F中的每一个函数依赖,得AB →C与B→D为AB,B X(1),置X(1)=AB ∪ C ∪ D=ABCD;
第二次: ② X(0)≠ ABCD,则X(0)=ABCD;
③找到C → E 与AC → B,置X(1)=ABCD ∪ E ∪ B=ABCDE;
第三次: ② X(0)≠ ABCDE,则X(0)=ABCDE;
③找到CE → B,置X(1)=ABCDE ∪ B=ABCDE;
第四次: ② X(0)=X(1),转④;
④结束,即X(1)=(AB)+=ABCDE。
(5)求关系模式候选码
例:R<U,F>,U=(A,B,C,D,E,G),F={AB-->C,CD-->E,E-->A.A-->G},求候选码。
因G只在右边出现,所以G一定不属于候选码;而B,D只在左边出现,所以B,D一定属于候选码;BD的闭包还是BD,则对BD进行组合,除了G以外,BD可以跟A,C,E进行组合
先看ABD,ABD本身自包ABD,而AB-->C,CD-->E,A-->G,所以ABD的闭包为ABDCEG=U
再看BDC, CD-->E,E-->A,A-->G,BDC本身自包(只有BDC才能推出BDC,BDC的子集均无法推出),所以BDC的闭包为BDCEAG=U
最后看BDE, E-->A,A-->G,AB-->C,BDE本身自包,所以BDE的闭包为BDEAGC=U因为(ABD)、(BCD)、(BDE)的闭包都是ABCDEG所以本问题的候选码有3个分别是ABC、BCD和BDE
如果没有L和R属性,只能慢慢试,要记住如果属性集X是候选码,那么任何包含X的属性集都不是候选码。
(6)求最小函数依赖集
例:关系模式R(A,B,C,D),F = {A→C,C→A,B→AC,D→AC}
将F中的依赖右部属性单一化:
F1={ A→C,C→A,B→A,B→C,D→A,D→C }。
去掉多余的函数依赖:由B→A,A→C可得B→C,所以F1中的B→C是多余的;由D→A,A→C可得D→C,所以F1中的D→C是多余的。可得F2={ A→C,C→A,B→A,D→A }。
寻找函数依赖集的最小集:
F2中所有依赖的左部都是单属性,不存在依赖左部有多余的属性。 如果左部有多属性,那么要判断对多属性的依赖是不是部分依赖。
总结:右部拆开,用Armstrong公理判断多余依赖,之后左部判断部分依赖。