假设某个老师刚刚被聘为研究生导师,但还没有招收学生(这种情况经常出现),这时也就没有他的研究生信息和研究生选修课程的信息,意味着“学号”和“课程名称”等属性的属性值为空(null)。如果这时在关系SSC中插入该导师的信息,则会产生异常。因为属性“学号”和“课程名称”是主码,其取值不能为空。这种异常就是插入异常。插入异常的存在使得添加导师信息的操作无法完成。
• 删除异常
假设某个导师刚招收了两名研究生,但过了一个学期以后,这两个研究生都因出国而注销学籍了。注销时,将这两个研究生对应的元组从关系SSC中删除(全部删除)。由于删除操作是以元组为单位进行的,所以导师信息也将全部被删除,以后就无法使用该导师的信息了,称为删除异常。
关系模式SSC还容易产生数据不一致等其他的一些问题。仅满足第一范式的关系模式确实还存在许多问题。人们在第一范式的基础上增加一些约束条件,从而得到第二范式。
2.5.2 第二范式(2NF)
定义2.9 设R(U)是一个关系模式,如果R(U)∈1NF且每个非主属性都完全函数依赖于任一候选码,则称R(U)属于第二范式,记为R(U)∈2NF。
l 第二范式是在第一范式的基础上,增加了条件“每个非主属性都完全函数依赖于任一候选码”,它比第一范式具有更高的要求。
l 如果一个关系模式的候选码都是由一个属性构成,该关系模式肯定属于第二范式,此时每个非主属性都显然完全函数依赖于任一候选码。
l 如果一个关系模式的属性全是主属性,则该关系模式也肯定属于第二范式,此时不存在非主属性。
【例2.7】例2.6中的关系模式SSC(学号, 姓名, 系别, 导师工号, 导师姓名, 导师职称, 课程名称, 课程成绩)。该关系的唯一候选码为{学号, 课程名称},因此“姓名”, “系别”, “导师工号”, “导师姓名”, “导师职称”, “课程成绩”等6个属性为其非主属性。不存在“学号”相同而“姓名”不同的研究生元组,“姓名”函数依赖于“学号”,即“学号→ 姓名”。非主属性“姓名”并非完全函数依赖于码{学号, 课程名称},此关系模式不属于第二范式。
Ø 因为关系模式SSC仅属于第一范式而不属于第二范式,这决定了它还存在数据冗余、插入异常和删除异常等问题。我们通过模式的投影分解,将之分解为若干个子模式,使得每个子模式都属于第二范式,从而解决上述问题。
Ø 先考察关系模式SSC中的函数依赖:
ü 学号→姓名
ü 学号→系别
ü 学号→导师工号
ü 导师工号→导师姓名
ü 导师工号→导师职称
ü {学号, 课程名称} 课程成绩
l 由于“学号”和“导师工号”都是单属性,因此上述函数依赖都是完全函数依赖,一共有三种类型,因此在进行投影分解后可得到如下的三个关系模式:
Ø Student(学号, 姓名, 系别, 导师工号)
Ø supervisor(导师工号, 导师姓名, 导师职称)
Ø course(学号, 课程名称, 课程成绩)
l 这三个关系模式的码分别为学号、导师工号和{学号, 课程名称},每个关系模式中非主属性都完全函数依赖于码。这三个关系模式都属于第二范式。
l 利用基于外码的自然连接可以将这三个关系合成原来的关系SSC,即 SSC = student⋈ 导师工号supervisor ⋈学号course。外码的设置如:“导师工号”是student的关于supervisor的外码,“学号”是course的关于student的外码。
l 一个关系模式的码都是由一个属性构成,该关系模式肯定属于第二范式,因为这时每个非主属性都显然完全函数依赖于码。
【例2.8】设有关系模式teacher(课程名, 任课教师名, 任课教师职称),表2.19为关系模式teacher的一张关系表。假设每名教师可以上多门课,每门课只由一名教师上,请问关系模式teacher属于几范式?