对于一个关系,既然其中的属性值(也就是数据)能够组合到一起,则它们之间就必须会有一定的依赖关系,而这就是数据依赖,数据依赖是一个关系内部属性与属性之间的一种约束关系。例如学校对学生信息的管理中,学号是学生存在的表示,这个学生的信息(例如姓名、专业、年级、成绩等)的组合使用“学号”这个关键属性进行约束的,所以学生的信息属性值对学号具有依赖关系。其中,主要的数据依赖有两种:函数依赖和多值依赖。函数依赖的一般定义如下:
假设R(U)是属性集U上的关系模式,X,Y是U的子集。对于R(U)的任意一个关系r,r中不可能存在这种情况:就是r中的两个(多个)元组在X上的属性值相等,而在Y上的属性值不等。则称X函数确定Y或Y函数依赖X,记作:X—>Y。例如:学生表中如果有两个元组的学号信息是相同的,那么这两个元组中的姓名信息就不可能不同;但是,如果两个元组的姓名信息是相同的,则这两个元组的学号信息未必相同(有学生同名的情况),这时候学号信息函数确定姓名信息,或者姓名信息函数依赖学号信息。X 和 Y之间的函数依赖关系有:
非平凡的函数依赖:X函数确定Y,但Y不包含于X(也就是说,Y中有的元素而X是没有的),称Y对X非平凡函数依赖。
平凡的函数依赖:X函数确定Y,但Y包含于X(也就是说,Y中所有的元素在X中都有),称Y对X平凡函数依赖。
完全函数依赖:X函数确定Y,但是没有任何一个X的真子集 X' 能够满足X' 函数确定Y,称Y对X完全函数依赖。
码的概念:若K是R(U)中的属性或属性组合,如果属性集合U中的所有属性都是完全函数依赖于K,则称K是R的候选码,如果有多个候选码,则可任选一个,作为R的主码。
总结了那么多数据依赖的内容,下面到了第二范式的总结阶段,第二范式的定义是:如果关系R属于第一范式,且每一个非主属性全部完全函数依赖于码,这该范式属于第二范式。
例如关系模式S-L-C(Sno,Sdept,Sloc,Cno,Grade),其中Sloc为学生的住处,且每个系(Sdept)的学生住在同一个地方,给定S-L-C的码是(Sno,Cno)。函数依赖关系有:
Grade完全函数依赖(Sno,Cno),因为Sno函数确定Sdept,所以Sdept部分函数依赖(Sno,Cno),同样Sloc也是部分函数依赖(Sno,Cno),因此关系S-L-C不属于第二范式。不属于第二范式的关系模式会产生以下几个问题:
1、插入异常,如要插入一个学生Sno=A993,Sdept=PHY,Sloc=BLD2,但是该学生还未选课,没有Cno,这样元组就不能插入到关系表中。
2、删除异常,如学生A993选了一门课C3,现在这门课他不想要了,想要删除,但由于C3是主属性,删除C3就得删除整个元组,使得A993的其他信息也被删除了,从而造成删除异常。
3、修改复杂,如果某个学生从MA系转到CS系,原本只需修改此学生元组中的Sdept分量,但因S-L-C中还有该系的住处Sloc属性,学生改变住处,因而还必须修改元组中的Sloc分量。
解决方案就是模式分解,将原来的模式分解为SC(Sno,Cno,Grade)、SL(Sno,Sdept,Sloc)。这样就可以达到第二范式了。