第5章 关系数据库模式的规范化设计 在一个关系数据库应用系统中,构成该系统的关系数据库的全局逻辑结构(逻辑模式)的基本表的全体,称为该数据库应用系统的关系数据库模式。 关系数据库模式设计是按照不同的范式(标准)对关系数据库模式中的每个关系模式进行分解,用一组等价的关系子模式代替原有的某个关系模式,即通过将一个关系模式不断地分解成多个关系子模式和建立模式之间的关联来消除数据依赖中不合理的部分,最终实现使一个关系仅描述一个实体或者实体间的一种联系的目的。关系数据库模式设计是数据库应用系统设计中的核心问题之一。 本章首先论述关系约束与关系模式的表示,然后讨论为什么要对关系模式进行规范化设计,在此基础上引出函数依赖的概念和函数依赖的公理体系,并给出函数依赖集的分解方法,接着给出保持无损分解的概念,并给出保持无损性的分解方法,最后给出关系模式的规范化方法。 5.1关系约束与关系模式的表示 假设在大学教学信息管理数据库应用系统的设计中,通过直接整理用户组织日常所用的相关教学管理表格,得到课程(归属)表、学生成绩表、授课(统计)表和教师信息表。将这几个关系表合并在一起,构成的大学教学信息管理数据库应用系统中除学生学籍关系表以外的其他关系表结构如表5.1所示。 表5.1大学教学信息管理数据库应用系统中部分表的属性 表名 课程(归属)表 学生成绩表 授课(统计)表 教师信息表 表拥有 的属性 课程号 学号 课程号 教师工号 课程名 姓名 课程名 教师姓名 学时 课程号 学时 教师性别 (归属)教研室 课程名 (任课)教研室 教师出生日期 分数 教师工号 职称 专业名称 教师姓名 (所在)教研室 职称 如果直接将图1.8(a)和表5.1中4个表的表名作为关系模式名,将各表中的属性作为各关系模式的属性,就可以得到如下5个关系模式。 (1) 学生学籍关系(学号,姓名,性别,出生日期,籍贯,专业代码,班级)。 (2) 课程关系(课程号,课程名,学时,教研室)。 (3) 学生成绩关系(学号,姓名,课程号,课程名,分数,专业名称)。 (4) 授课关系(课程号,课程名,学时,教研室,教师工号,教师姓名,职称)。 (5) 教师关系(教师工号,教师姓名,教师性别,教师出生日期,职称,教研室)。 按照一般的语义概念分析以上的关系模式可知,一个关系模式中的属性的全体构成了该关系模式的属性集合(设U表示关系模式的属性集合); 每个属性的值域(设D表示各属性的值域集合)实质上构成了对该关系的一种取值约束,并反映了属性集合向属性值域集合的映射或约束(设DOM表示属性集U到值域集合D的映射)。 同时,在每个关系表中都存在由一些属性的值决定另一些属性的值的数据依赖关系。例如,在课程关系中,给定一个“课程号”的值,就可以确定开设该课程的教研室的名称; 在教师关系中,给定一个“教职工号”的值,就可以确定该教师所在的教研室的名称。由于这种依赖是用属性的值体现的,所以称为数据依赖; 当用属性名集合表示其依赖关系时,就可以看作一种函数依赖(设F表示函数依赖集合)。 第 5 章 关系数据库模式的规范化设计 数据库原理及应用(SQL Server)(第5版) 综上,当把所有这些要素完整地反映到关系模式的描述中时,就可以得到如下结论。一个关系模式应该完整地用一个五元组{R,U,D,DOM,F}表示,并一般地记为 R(U,D,DOM,F) 其中,R是关系名; U是关系R的全部属性组成的属性集合; D是U中各属性的值域的集合; DOM是属性集U到值域集合D的映射; F是关系R的属性集U上的函数依赖集合。 在本章的关系数据库设计理论的相关概念讨论中,关系名R、属性集U和依赖集F三者相互关联,相互依存,而D和DOM在讨论各概念的描述时关联性不是很大。所以为了简单起见,在本书后续内容的介绍中把关系模式简化地看作一个三元组R(U,F)。当且仅当U上的一个关系R满足F时,将R称为关系模式R(U,F)上的一个关系。 需要进一步说明的是,在本章后续的内容中会涉及较多且比较严格的定义、定律和公式推导,为了表述上的方便,如不做特殊声明,总是假设有如下约定。 (1) 用大写英文字母A、B、C、D等表示关系的单个属性。 (2) 用大写字母U表示某一关系的属性集(全集),用大写字母V、W、X、Y、Z表示属性集U的子集。 (3) 不再特意地区分关系和关系模式,并用大写字母R、R1、R2、……和S、S1、S2、……表示关系和关系模式。 (4) R(A,B,C)、R(ABC)和ABC这3种表示关系模式的方法是等价的。同理,{A1,…,An}和A1…An是等价的,X∪Y和XY是等价的,X∪{A}和XA是等价的。 (5) 用大写英文字母F、F1、……以及G表示函数依赖集。 (6) 若X={A,B},Y={C,D},则X→Y、{A,B}→{C,D}和AB→CD这3种函数依赖表示方法是等价的。 5.2对关系模式规范化设计的必要性 本节先介绍关系模式规范化设计的必要性,然后介绍由此引出的关系模式分解的相关问题及解决思路。 5.2.1对关系模式进行规范化设计的必要性 本节用一个由于构建的关系模式不合理而引起操作异常的例子说明对关系模式进行规范化设计的必要性。 对于5.1节的授课关系模式(调整了其中一些属性的顺序): 授课关系(课程号,课程名,学时,教研室,教师工号,教师姓名,职称) 可得用符号形式表示的授课统计关系模式为 TEACHES(T#,TNAME,TITLEOF,TRSECTION,C#,CNAME,CLASSH) 则这个关系模式在使用过程中会存在以下操作异常问题。 1) 数据冗余 对于每位教师所讲的每一门课,教师姓名、职称、教研室等信息都要重复存放,会造成大量的数据冗余。 2) 更新异常 由于有数据冗余,如果某教师的职称或教研室变化,就必须对所有具有教师职称或所属教研室的元组进行修改。这不仅增加了更新的代价,而且可能出现一部分元组修改了,另一部分元组没有被修改的情况,存在着潜在的数据不一致性。 3) 插入异常 由于这个关系模式的主键由教师工号T#和课程号C#组成,如果某一位教师刚调来,或某一位教师因为某种原因没有上课,就会由于关系的主键属性值不能为空(NULL)而无法将该教师的教师姓名、职称、教研室等基本信息输入数据库中。学校的数据库中没有该教师的信息,就相当于该学校没有这位教师,显然是不符合实际情况的。 4) 删除异常 如果某教师不再上课,则在删除该教师所担任的课程信息的同时,就会连同该教师的教师姓名、职称、教研室等基本信息都删除了。 以上表明,上述TEACHES关系模式的设计是不合适的。之所以存在这种操作异常,是因为在数据之间存在着一种依赖关系。例如,某位教师的职称或所属教研室只由其教师工号就可以确定,而与所上课程的课程号无关。 如果将上述关系模式分解为以下两个关系模式: TEACHER(T#,TNAME,TITLEOF,TRSECTION) COURSE(C#,CNAME,CLASSH) 就不会存在上述的操作异常了。一个教师的基本信息不会因为他没上课而不存在; 某门课程也不会因为某学期没有上而被认为是没有开设的课程。 5.2.2关系模式分解的思路 进一步分析授课关系TEACHES可知,其属性集U可表示为 U={T#,TNAME,TITLEOF,TRSECTION,C#,CNAME,CLASSH} 如果给定一个教师工号T#的值,就能唯一地确定出该教师的姓名TNAME、职称TITLEOF和所在教研室TRSECTION的值。例如以图1.8的关系当前值为例,当给出T#的值为T0401001时,就能得到该教师工号对应的TNAME、TITLEOF和TRSECTION的值为{张国庆,教授,计算机}。这就是说,在该关系模式中存在着{T#}决定{TNAME,TITLEOF,TRSECTION}的函数依赖关系,即 {T#}→{TNAME,TITLEOF,TRSECTION} 同理,也存在着下述两个函数依赖: {C#}→{CNAME,CLASSH} {T#,C#}→{TNAME,TITLEOF,TRSECTION,CNAME,CLASSH} 综上分析可知,对于关系模式TEACHES(U,F)来说,有 U={T#,TNAME,TITLEOF,TRSECTION,C#,CNAME,CLASSH} F={{T#,C#}→{TNAME,TITLEOF,TRSECTION,CNAME,CLASSH}, {T#}→{TNAME,TITLEOF,TRSECTION},{C#}→{CNAME,CLASSH}} 显然,当把关系模式TEACHES(U,F)分解成 TEACHER(T#,TNAME,TITLEOF,TRSECTION) COURSE(C#,CNAME,CLASSH) 时,可以对应地将它们表示为TEACHER(U1,F1)和COURSE(U2,F2),且有 U1={T#,TNAME,TITLEOF,TRSECTION} F1={{T#}→{TNAME,TITLEOF,TRSECTION}} U2={C#,CNAME,CLASSH} F2={{C#}→{CNAME,CLASSH}} 5.2.3关系模式分解的定义 将上述的关系模式分解思路可概念化地抽象成如下关系模式分解定义。 定义5.1设有关系模式R(U,F),如果U=U1∪U2∪…∪Uk,并且对于任意的i,j(1≤i,j≤k),UiUj不成立,且Fi中的每个函数依赖X→Y的决定因素X和被决定因素Y中的属性都在Ui中(即Fi是F在Ui上的投影,详见5.3.6节),则称ρ={R1(U1,F1),R2(U2,F2),…,Rk(Uk,Fk)}是关系模式R(U,F)的一个分解。 定义5.1中的关键点是,对于属性子集集合{U1,U2,…,Uk}中的任意属性子集Ui及1≤i≤k 和Uj及1≤j≤k,UiUj既不成立,UjUi也不成立。即属性子集集合{U1,U2,…,Uk}中的任意一个属性子集不是其他任何一个属性子集的子集。 如何将F分解成F1和F2,即是5.3节将要介绍的函数依赖集分解方法; 如何将U分解成U1和U2,即是5.4节将要介绍的关系模式(属性集)分解方法。 5.3函数依赖集分解方法 函数依赖(functional dependency)是关系所表述的信息本身所具有的特性,换而言之,函数依赖不是研究关系由什么属性组成或关系的当前值如何确定,而是研究施加于关系的只依赖于值的相等与否的限制。这类限制并不取决于某元组在它的某些分量上取什么值,而仅取决于两个元组的某些分量是否相等。正是这种限制给数据库模式的设计产生了重大而积极的影响。 5.3.1函数依赖的定义 定义5.2设有关系模式R(A1,A2,…,An)和属性集U={A1,A2,…,An}的子集X、Y。如果对于具体关系r的任何两个元组u和v,只要u[X]=v[X],就有u[Y]=v[Y],则称X函数决定Y,或Y函数依赖X,记为X→Y。 【例5.1】对于图1.11中的学生关系模式: S(S#,SNAME,SSEX,SBIRTHIN,PLACEOFB,SCODE#,CLASS) 有X={S#},Y={SNAME,SSEX,SBIRTHIN,PLACEOFB,SCODE#,CLASS}。 也就是说,对于图1.8的大学教学信息管理数据库中的学生关系S的具体关系rs(即关系S的当前值)来说,不可能同时存在这样的两个元组: 它们对于子集X={S#}中的每个属性有相等的分量,但对于子集Y={SNAME,SSEX,SBIRTHIN,PLACEOFB,SCODE#,CLASS}中的某个或某些属性具有不相等的分量。例如,对于X={201401003},只能唯一地找到王丽丽同学的性别为“女”,出生日期为“19970202”,籍贯为“上海”,专业代码为“S0401”,班级为“201401”,所以有X→Y。当然,并不是说依据某一具体的关系就可以验证该关系上的函数依赖是否成立,函数依赖是针对作为关系模式R的所有可能的值的。 由函数依赖的定义和例5.1可知,若关系模式R中属性之间的关系可用一个函数依赖X→Y表示,则决定因素X即为该关系的主键。 进一步分析可知,函数依赖是一种语义范畴的概念,所以要从语义的角度来确定各关系的函数依赖。例如,以学号为唯一主键属性的假设是认为不同的学生一定有不同的、唯一的学号。图5.1用图示方式直观地说明了学习关系SC的函数依赖{S#,C#}→{GRADE}。 图5.1学习关系中的函数依赖 函数依赖描述了每个关系中主属性与非主属性之间的关系。对于关系R(A1,A2,…,An)和函数依赖X→Y来说,属性子集X中包括且仅包括关系R的主属性,对于关系R的任何属性子集Y,X→Y一定成立。也就是说,对于X→Y,可能存在YX和YX两种情况,所以约定: (1) 若有X→Y,但YX,则称X→Y为非平凡函数依赖。 (2) 若X→Y,且YX,则称X→Y为平凡函数依赖。 若不特别声明,总假定本章所讨论的是非平凡函数依赖。 5.3.2具有函数依赖约束的关系模式 由函数依赖的概念可知: 在一个关系模式中由函数依赖表征的、由一个属性或一组属性组成的被决定因素的值,对由一个属性或一组属性组成的决定因素的值的依赖性,实质上反映了一个关系模式中不同属性集的值之间存在的约束关系。当把所有这种约束反映到对关系模式的描述时,就可以进一步由关系的属性集合和属性间的函数依赖(集合)来表示关系。例如,图1.11的大学教学信息管理数据库应用系统的关系模式可进一步表示为图5.2的形式。 图5.2具有函数依赖约束的关系模式表示示例 对学习关系SC来说,有U={S#,C#,GRADE},且设X={S#,C#},Y={GRADE}和F={X→Y},则学习关系可一般地表示为 SC({S#,C#,GRADE},{{S#,C#}→{GRADE}})或SC(U,F) 5.3.3函数依赖的逻辑蕴涵 在研究函数依赖时,有时需要根据已知的一组函数依赖判断另外一个或一些函数依赖是否成立,或是否能从已知的函数依赖中推导出其他函数依赖,这就是函数依赖的逻辑蕴涵要讨论的问题。 定义5.3设有关系模式R(U,F),X、Y是属性集U={A1,A2,…,An}的子集,如果从F中的函数依赖能够推导出X→Y,则称F逻辑蕴涵X→Y,或称X→Y是F的逻辑蕴涵。 所有被F逻辑蕴涵的函数依赖组成的依赖集称为F的闭包(closure),记为F+。一般有FF+。 显然,如果能计算出F+,就可以很方便地判断某个函数依赖是否包含在F+中,即被F逻辑蕴涵,但函数依赖集F的闭包F+的计算是一件十分麻烦的事情,即使F不大,F+也比较大。例如,有关系模式R(A,B,C),其函数依赖集为F={A→B,B→C},则F的闭包为 F+=A→,AB→,AC→,ABC→,B→,C→ A→A,AB→A,AC→A,ABC→A,B→B,C→C A→B,AB→B,AC→B,ABC→B,B→C, A→C,AB→C,AC→C,ABC→C,B→BC, A→AB,AB→AB,AC→AB,ABC→AB,BC→, A→AC,AB→AC,AC→AC,ABC→AC,BC→B, A→BC,AB→BC,AC→BC,ABC→BC,BC→C, A→ABC,AB→ABC,AC→ABC,ABC→ABC,BC→BC, 5.3.4函数依赖的公理体系 由前述内容可知,对于关系模式R(U,F)来说,为了从关系模式R(U,F)的函数依赖集F中的函数依赖确定该关系的主键,需要分析各函数依赖之间的逻辑蕴涵关系,或者至少要根据给定的函数依赖集F和函数依赖X→Y确定X→Y是否属于F+,这显然涉及F+的计算。由于F+的计算是一件非常复杂的事情,经过一些学者的潜心研究,提出了一组推导函数依赖逻辑蕴涵关系的推理规则,并由W.W.Armstrong于1974年归纳成公理体系,这就形成了著名的Armstrong(阿姆斯特朗)公理体系。Armstrong公理体系包括公理和规则两部分。 1. 阿姆斯特朗公理 定义5.4设有关系模式R(U,F)和属性集U={A1,A2,…,An}的子集X、Y、Z、W,阿姆斯特朗公理包括如下内容。 自反律: 若XY,则X→Y。 增广律: 若X→Y,则XZ→YZ。 传递律: 若X→Y,Y→Z,则X→Z。 从理论上讲,公理(定义)是永真而无须证明的,但为了进一步理解函数依赖的定义和加深理解,下面从函数依赖的定义出发,给出公理的正确性证明。 定理5.1阿姆斯特朗公理是正确的。 证明: (1) 证明自反律是正确的。设r为关系模式R的任意一个关系,u和v为r的任意两个元组。 若u[X]=v[X],则u和v在X的任何子集上必然相等。 由条件XY,所以有u[Y]=v[Y]。 由r、u、v的任意性,并根据函数依赖的定义5.2,可得X→Y。 (2) 证明增广律是正确的。设r、u和v的含义同上,并设u[XZ]=v[XZ],则u[X]u[Z]=v[X]v[Z]。 由条件X→Y,若u[X]=v[X],则u[Y]=v[Y],并推知u[Z]=v[Z]。 所以u[Y]u[Z]=v[Y]v[Z],则有u[YZ]=v[YZ]。 根据函数依赖的定义5.2,可得XZ→YZ。 (3) 证明传递律是正确的。设r、u和v的含义同上,由条件X→Y,若u[X]=v[X],则u[Y]=v[Y]。 又由条件Y→Z,若u[Y]=v[Y],则u[Z]=v[Z]。 所以推知若u[X]=v[X],则u[Z]=v[Z]。 根据函数依赖的定义5.2,可得X→Z。证毕。 2. 阿姆斯特朗公理的推论 从阿姆斯特朗公理可以得出下面的推论。 推论5.1(合并规则): 若X→Y且X→Z,则X→YZ。 推论5.2(分解规则): 若X→Y且ZY,则X→Z。 推论5.3(伪传递规则): 若X→Y且WY→Z,则XW→Z。 证明: 下面用阿姆斯特朗公理分别证明3个推论的正确性。 1) 证明推论5.1 由条件X→Y,根据增广律可得X→XY。 由条件X→Z,根据增广律可得XY→YZ。 根据传递律,由X→XY和XY→YZ,可得X→YZ。 2) 证明推论5.2 已知有X→Y,由条件ZY,根据自反律可得Y→Z。 根据传递律,由X→Y和Y→Z,可得X→Z。 3) 证明推论5.3 由条件X→Y,根据增广律可得XW→WY。 根据传递律和已知条件WY→Z,可得XW→Z。证毕。 【例5.2】对于关系模式R(CITY,STREET,ZIP),依赖集F={ZIP→CITY,{CITY,STREET}→ZIP},候选键为{CITY,STREET}和{ZIP,STREET}。请证明{CITY,STREET}→{CITY,STREET,ZIP}和{STREET,ZIP}→{CITY,STREET,ZIP}成立。现证明后者。 证明: 已知有ZIP→CITY,由增广律可得 {STREET,ZIP}→{CITY,STREET}。 又已知{CITY,STREET}→ZIP,由增广律可得 {CITY,STREET}→{CITY,STREET,ZIP}。 由上述所得的两个结论,并根据传递律即可得到 {STREET,ZIP}→{CITY,STREET,ZIP}。证毕。 定理5.2如果有关系模式R(A1,A2,…,An),则X→A1A2…An成立的充要条件是X→Ai(i=1,2,…,n)均成立。 由合并规则和分解规则即可得到这个定理,其证明作为练习留给读者自己完成。 定理5.2的结论为数据库模式设计中各关系的主键的确定奠定了理论基础。 5.3.5X关于F的闭包及其计算 判断某个函数依赖是否被F逻辑蕴涵最直接的方法需要计算F+,但由于F+的计算比较复杂,人们经过研究提出了一种使用X关于F的闭包X+F来判断函数依赖X→Y是否被F逻辑蕴涵的方法,且由于X+F的计算比较简单,在实际中得到了较好的应用。 1. X关于F的闭包X+的概念 定义5.5设有关系模式R(U,F)和属性集U={A1,A2,…,An}的子集X,则称所有用阿姆斯特朗公理从F推出的函数依赖X→Ai的属性Ai组成的集合为X关于F的闭包,记为X+F,通常简记为X+,即 X+={Ai|用公理从F推出的X→Ai} 显然有XX+。 2. 使用X关于F的闭包定义计算X+ 【例5.3】已知在关系模式R(A,B,C)上有函数依赖F={A→B,B→C},求X分别等于A、B、C时的X+。 解: (1) 对于X=A,根据自反律有A→A; 已知有A→B,且由已知的A→B,B→C,根据传递率可推得A→C,所以有X+=ABC。 (2) 对于X=B: 根据自反律有B→B; 且已知B→C,所以有X+=BC。 (3) 对于X=C,显然有X+=C。 由例5.3可见,比起F的闭包F+的计算,X关于F的闭包X+的计算要简单得多。 3. 使用X+判断某一函数依赖是否能从F导出的方法 定理5.3设有关系模式R(U,F)和属性集U={A1,A2,…,An}的子集X、Y,则X→Y能用阿姆斯特朗公理从F导出的充要条件是YX+。 证明: (1) 充分性证明: 设Y=A1,A2,…,An,AiU(i=1,2,…,n)。假设YX+,由X关于F的闭包X+的定义,对于每一个i,Ai能由公理从F导出。再使用合并规则(推论5.1),即可得X→Y。 (2) 必要性证明: 设Y=A1,A2,…,An,AiU(i=1,2,…,n)。假设X→Y能由公理导出,根据分解规则(推论5.2)和定理5.2有X→A1,X→A2,…,X→An,由X+的定义可知,AiX+(i=1,2,…,n),所以YX+。证毕。 定理5.3的意义是,把判定X→Y是否能从F根据阿姆斯特朗公理导出,即该函数依赖是否被F蕴涵的问题,转换成X+是否包含Y的问题: 当X+包含Y时,说明X→Y能从F根据阿姆斯特朗公理导出。 4. 计算X关于F的闭包X+的算法 算法5.1求属性集X关于函数依赖集F的闭包X+。 输入: 关系模式R的全部属性集U,U上的函数依赖集F,U的子集X。 输出: X关于F的闭包X+。 计算方法: (1) X(0)=X。 (2) 如果F中的所有函数依赖的左端属性都不被X(i)包含,或F为空集,转(4)。 (3) 否则,依次考察F中的每一个函数依赖,如果X(i)包含了某个函数依赖左端的属性,就把该函数依赖右端的属性添加到X(i)中,并把该函数依赖从F中去掉。即对于F中的某个V→W,若有VX(i),则有X(i+1)=X(i)W; 并得到新的F=F-{V→W}。接下来转(2)。 (4) 此时的X(i)即为求得的X关于F的闭包X+,输出X+。 【例5.4】已知有函数依赖集F={AB→C,BC→D,ACD→B,D→EH,BE→C},属性集U={A,B,C,D,E,H},X=BD,求X+。 解: (1) X(0)=BD。 (2) 依次考察F中的函数依赖,由于X(0)包含D→EH的左端属性D,所以将其右端属性EH添加到X(0)中,得到X(1)=BDEH,并通过计算F=F-{D→EH}得到新的F={AB→C,BC→D,ACD→B,BE→C}。 (3) 重新依次考察F中的函数依赖,由于X(1)包含BE→C的左端属性BE,所以将其右端属性C添加到X(1)中,得到X(2)=BCDEH,并得到新的F={AB→C,BC→D,ACD→B}。 (4) 重新依次考察F中的函数依赖,虽然X(2)包含BC→D的左端属性BC,但其右端属性D已经包含在X(2)中,所以得到新的F={AB→C,ACD→B}。 (5) 进一步依次考察F中的函数依赖,发现F中剩余的函数依赖AB→C和ACD→B的左端属性都不被X(2)包含,计算终止。 (6) 此时得到X(2)=BCDEH,即为求得的X+,输出结果X+=BCDEH。 5.3.6函数依赖集的分解方法 下面介绍函数依赖集分解过程中用到的函数依赖集的投影概念。 1. F在Ui上的投影 根据关系模式为R(U,F)的约定,对关系模式的分解必然涉及对依赖集F中的各依赖的划分,由于这种划分是根据分解成的各子关系模式的属性来进行的,所以涉及F在各子关系模式的属性集Ui上的投影概念。 定义5.6设Ui是属性集U的一个子集,则函数依赖集合{X→Y|X→Y∈F+∧XYUi}的一个覆盖Fi称为F在Ui上的投影。 按照依赖集覆盖(等价)的定义,定义5.6的含义是,对于属性集U的子集Ui,存在一个与其对应的依赖子集Fi,且由Fi中的每个函数依赖X→Y的决定因素X和被决定因素Y组成的属性子集XY均是Ui的子集。 在下面的关系模式分解定义中将会看到,当一个关系模式R(U,F)分解时,除了要将其属性集U={A1,A2,…,An}分解成k个属性子集Ui且1≤i≤k外,也要将依赖集F分解成k个依赖子集Fi且1≤i≤k。定义5.6的意义就在于给出了组成Fi中的各函数依赖应满足的条件。 在定义5.6的基础上,可进一步给出意义更明确的F在Ui上的投影的定义。 定义5.7设有关系模式R(U,F)和U={A1,A2,…,An}的子集Z,把F+中所有满足XYZ的函数依赖X→Y组成的集合称为依赖集F在属性集Z上的投影,记为πZ(F)。 由定义5.7,显然有πZ(F)={X→Y|X→Y∈F+,且XYZ},所以定义5.7和定义5.6本质上是相同的。 2. 保持依赖的分解 在关系模式的分解中有一个重要的性质,就是要求分解后的子模式还应保持原关系模式的函数依赖,即分解后的子模式应保持原有关系模式的完整性约束,这就是保持依赖的分解要讨论的问题。 定义5.8设有关系模式R(U,F),ρ={R1,R2,…,Rk}是R上的一个分解。如果所有函数依赖集πRi(F)(i=1,2,…,k)的并集逻辑蕴涵F中的每一个函数依赖,则称分解ρ具有依赖保持性,即分解ρ保持依赖集F。 基于定义5.8,可得保持函数依赖分解的判定方法。 (1) 对ρ中的每一个Ri求Fi=πRi(F)。 (2) 求∪ki=1πRi(F)。 (3) 判断F中每一个函数依赖X→Y 是否能从∪ki=1πRi(F)推出,如果均能推出,则分解ρ保持函数依赖,即具有函数依赖性; 否则分解ρ不保持函数依赖,即不具有函数依赖性。 【例5.5】已知关系模式R(U,F),U={S#,SD,SM},F={S#→SD,SD→SM}。通过对关系R的3种不同分解方法,根据定义5.8判断各分解方法是否为保持依赖的分解。 解: (1) 方法1。 设关系模式R(U,F)被分解成ρ1={R1(S#,),R2(SD,),R3(SM,)}。 对F在各Ri上进行投影,有Fi=πRi(F) =(表示空集),且有 F1∪F2∪F3=∪∪=≠F 所以分解ρ1不保持原关系R的函数依赖性,即该分解不保持依赖。 (2) 方法2。 设关系模式R(U,F)被分解成ρ2={R1({S#,SD},{S#→SD}),R2({S#,SM},{S#→SM})}。 因为πR1(F)∪πR2(F)={S#→SD}∪{S#→SM} ={S#→SD,S#→SM} 显然,对于F中的SD→SM,有(SD→SM){S#→SD,S#→SM} 即πR1(F)和πR2(F)的并集不逻辑蕴涵F中的函数依赖SD→SM,所以分解ρ2不保持函数依赖。 (3) 方法3。 设关系模式R(U,F)被分解成ρ3={R1({S#,SD},{S#→SD}),R2({SD,SM},{SD→SM})}。 因为πR1(F)∪πR2(F)={S#→SD}∪{SD→SM} ={S#→SD,SD→SM } =F 所以分解ρ3保持原关系R的函数依赖性。 5.4关系模式的分解方法 在数据库应用系统设计中,一方面是为了减少冗余,另一方面是为了解决可能存在的插入、删除和修改等的操作异常,经常需要将包含属性较多的关系模式分解成几个包含属性较少的关系模式,下面讨论关系模式分解中的相关问题。 5.4.1保持无损分解的概念 定义5.9设有关系模式R(U,F),ρ=(R1,R2,…,Rk)是R的一个分解。如果对于R的任一满足F的关系r,r=πR1(r)πR2(r)…πRk(r)成立,则称该分解ρ是无损连接分解,也称该分解ρ是保持无损的分解。 上述定义说明,r是它在各Ri上的投影的自然连接。按照自然连接的定义,上式中两个相邻的关系在作自然连接时,如果至少有一个列名相同,则为自然连接; 如果没有相同的列名,则为笛卡儿积运算。 【例5.6】已知关系模式R(U,F),U={S#,SD,SM},F={S#→SD,SD→SM},并设关系R有如图5.3的当前值r。通过对关系R的3种不同分解方法,根据定义5.9判断各分解方法是否为无损连接分解。 图5.3例5.6关系R的当前值r 解: (1) 方法1。 设关系模式R(U,F)被分解成ρ1={R1(S#,),R2(SD,),R3(SM,)}。 对图5.3的已知具体关系r在Ui上进行投影,可得Ri=R(Ui)的各ri的当前值如图5.4所示。 图5.4Ri的当前值ri 根据定义5.9,计算r=r1r2r3=r1×r2×r3可得(在各ri没有相同属性的情况下,其自然连接运算即是笛卡儿积运算): S1 D1 M1,S2 D1 M1,S3 D1 M1, S1 D1 M2,S2 D1 M2,S3 D1 M2, S1 D2 M1,S2 D2 M1,S3 D2 M1, S1 D2 M2,S2 D2 M2,S3 D2 M2, S1 D3 M1,S2 D3 M1,S3 D3 M1, S1 D3 M2,S2 D3 M2,S3 D3 M2, 比较给定关系R的当前值r和所得元组集合(通过自然连接恢复的结果)可知,恢复后的关系R的当前值r已经丢失了原来信息的真实性(比原来的元组数多出许多)。所以分解ρ1是有损原来信息的一种分解,或者说分解ρ1不保持信息无损,不具有无损连接性。 (2) 方法2。 设关系模式R(U,F)被分解成ρ2={R1({S#,SD},{S#→SD}),R2({S#,SM},{S#→SM})}。 对图5.3的已知具体关系r在Ui上投影,可得Ri=R(Ui)的各ri的当前值如图5.5所示。 图5.5Ri的当前值ri 计算r=r1r2可得其结果与图5.3相同,说明分解ρ2是保持无损连接的分解。 (3) 方法3。 设关系模式R(U,F)被分解成ρ3={R1({S#,SD},{S#→SD}),R2({SD,SM},{SD→SM})}。 对图5.3的已知具体关系r在Ui上投影,可得Ri=R(Ui)的各ri的当前值如图5.6所示。 图5.6Ri的当前值ri 计算r=r1r2可得其结果与图5.3相同,说明分解ρ3是保持无损连接的分解。 在例5.6中,由于元组个数比较少,根据定义5.9和分解后的当前关系判断分解后的各关系是否为无损分解还是比较方便的; 但是当一个关系的当前值具有成千上万个元组时,判断其分解后的若干子关系是否为无损连接分解就比较麻烦。为此,引入下面的判断保持无损连接分解的方法。 5.4.2分解成两个以上子关系模式保持无损的判别方法 算法5.2判断一个分解是无损连接分解,即该分解是否具有无损连接性。 输入: 关系模式R(A1,A2,…,An),函数依赖集F,R的一个分解ρ=(R1,R2,…,Rk)。 输出: ρ是否为无损连接的判断。 方法: (1) 构造一个k行n列的表,其中第i行对应于关系模式R分解后的模式Ri,第j列对应于关系模式R的属性Aj。表中第i行第j列位置的元素的填入方法为: 如果Aj在Ri中,则在第i行第j列的位置填符号aj,否则填符号bij。 (2) 对于F中的所有函数依赖X→Y,在表中寻找在X的各属性上都分别相同的行,若存在两个或多个这样的行,则将这些行上对应于Y属性上的元素值修改成具有相同符号的元素值,修改Y属性上各行值的方法如下。 ① 只需这些行的Y属性上的某一行的值为aj(j为Y属性对应的那些列的列序号,且j=1,2,…,n)时,把这些行的Y属性列上的元素值都修改成aj。 ② 当这些行的Y属性列中的值没有aj时,则以Y属性列中下标较小的bij为基准,把这些行的Y属性列上的其他元素值都修改成bij。 (3) 按(2)逐个考察F中的每一个函数依赖,如果发现某一行变成了a1,a2,…,an,则分解ρ具有无损连接性; 如果直到检验完F中的所有函数依赖也没有发现这样的行,则分解ρ不具有无损连接性。 【例5.7】设有关系模式R(A,B,C,D,E),函数依赖集F={A→C,B→C,C→D,DE→C,CE→A},分解ρ={R1,R2,R3,R4,R5},其中R1=AD,R2=AB,R3=BE,R4=CDE,R5=AE。检验分解ρ是否具有无损连接性。 解: (1) 构造一个5行5列的表,并按算法5.2的(1)填写表中的元素,如图5.7所示。 图5.7例5.7第(1)步的结果 (2) 对于函数依赖A→C,在表中A属性列的1、2、5行都为a1,在C属性列的1、2、5行不存在a3,所以以该列第1行的b13为基准,将该列第2、5行位置的元素修改成b13,其结果如图5.8所示。 图5.8例5.7第(2)步的结果 (3) 对于函数依赖B→C,在表中B属性列的2、3行都为a2,在C属性列的2、3行不存在a3,所以以该列第2行的b13为基准,将该列第3行位置的元素修改成b13,其结果如图5.9所示。 图5.9例5.7第(3)步的结果 (4) 对于函数依赖C→D,在表中C属性列的1、2、3、5行都为b13,在D属性列的1行存在a4,所以将该列第2、3、5行位置的元素修改成a4,其结果如图5.10所示。 图5.10例5.7第(4)步的结果 (5) 对于函数依赖DE→C,在表中DE属性列的3、4、5行都相同,在C属性列的4行存在a3,所以将该列第3、5行位置的元素修改成a3,其结果如图5.11所示。 图5.11例5.7第(5)步的结果 (6) 对于函数依赖CE→A,在表中CE属性列的3、4、5行都相同,在A属性列的5行存在a1,所以将该列第3、4行位置的元素修改成a1,其结果如图5.12所示。 图5.12例5.7第(6)步的结果 这时表中的第3行变成了a1,a2,…,a5,所以分解ρ具有无损连接性。 算法5.2适用于关系模式R被分解成两个以上子关系模式的情况。如果只将关系模式R分解为两个关系模式,可以用定理5.4给出的检验方法进行检验。 5.4.3分解成两个子关系模式保持无损的判别方法 定理5.4设有关系模式R(U,F),ρ=(R1,R2)是R的一个分解,当且仅当(R1∩R2)→(R1-R2)∈F+或(R1∩R2)→(R2-R1)∈F+时ρ具有无损连接性。 证明: 分别将R1∩R2、R1-R2、R2-R1看成不同的属性集,并用算法5.2构造如图5.13所示的2行k列的表。 图5.13用算法5.2构造2行k列的表 (1) 充分性证明: 假设(R1∩R2)→(R1-R2)在F中,由算法5.2可将表中第2行的b2,i+1…b2,j改成ai+1…aj,使第2行变成a1 …ak。因此分解ρ具有无损连接性。 如果(R1∩R2)→(R1-R2)不在F中,但在F+中,则可用公理从F中推出(R1∩R2)→Ay,其中Ay∈(R1-R2),即Ay是R1-R2中的任一属性。所以用算法5.2可以将属性Ay列所对应的第2行中的b2y改为ay,这样修改后的第2行就变成了a1…ak,所以分解ρ具有无损连接性。 同理,对于(R1∩R2)→(R2-R1),可类似地证得表中的第1行为a1…ak。 (2) 必要性证明: 假设分解ρ具有无损连接性,那么按照算法5.2构造的表中必有一行为a1…ak。按照算法5.2的构造方法,若第2行为a1…ak,则意味着(R1∩R2)→(R1-R2)成立; 若第1行为a1…ak,则意味着(R1∩R2)→(R2-R1)成立。证毕。 上面的必要性证明也可以这样来理解: 根据定义5.9,如果关系模式R的分解ρ是满足函数依赖集F的无损连接分解,则对于R的任一满足F的具体关系r,必然有((R1∩R2)→(R1-R2))∈F,或者用公理可由F推出(R1∩R2)→(R1-R2)。同理,有(R1∩R2)→(R2-R1)的情况。 【例5.8】设有关系模式R(A,B,C),函数依赖集F={A→B,C→B},分解ρ={R1,R2},其中R1=AB,R2=BC。检验分解ρ是否具有无损连接性。 解: 因为(R1∩R2)→(R1-R2) = (AB∩BC)→AB-BC = (B→A)F (R2∩R1)→(R2-R1) = (BC∩AB)→BC-AB = (B→C)F 进一步分析可知,(B→A)F+且(B→C)F+ 所以分解ρ不具有无损连接性。 【例5.9】在例5.6中,已知有关系模式R(S#,SD,SM),函数依赖集F={S#→SD,SD→SM}。对于其中的方法(2),已知有分解ρ2={R1({S#,SD},{S#→SD}),R2({S#,SM},{S#→SM})},且已求解知该分解是无损连接分解。用定理5.4的方法验证分解ρ2具有无损连接性。 解: 因为 (R1∩R2)→(R1-R2)=({S#,SD}∩{S#,SM})→({S#,SD}-{S#,SM}) =S#→SD∈F 所以分解ρ2具有无损连接性。 【例5.10】在例5.6中,已知有关系模式R(S#,SD,SM),函数依赖集F={S#→SD,SD→SM}。对于其中的方法(3),已知有分解ρ3={R1(S#,SD),R2(SD,SM)},且已求解知该分解是无损连接分解。用定理5.4的方法验证分解ρ2具有无损连接性。 解: 虽然(R1∩R2)→(R1-R2)=({S#,SD}∩{SD,SM})→({S#,SD}-{SD,SM}) = SD→S#F+ 但是(R2∩R1)→(R2-R1)=({SD,SM}∩{S#,SD})→({SD,SM}-{S#,SD}) = SD→SM∈F+ 所以分解ρ3具有无损连接性。 这里要特别指出,定理5.4并不要求(R1∩R2)→(R1-R2)∈F+和(R2∩R1)→(R2-R1)∈F+同时成立,而是只要(R1∩R2)→(R1-R2)∈F+或(R2∩R1)→(R2-R1)∈F+之一成立即可。 例5.5和例5.6分别对同一关系R的3种不同分解方法进行了是否为保持依赖的分解和保持无损的分解的判断,其后的相关例子又对其进行了验证,结果是: 方法1既不保持信息无损,也不保持函数依赖; 方法2保持信息无损,但不保持函数依赖; 方法3既保持信息无损,又保持函数依赖。所以,对一个关系模式的保持无损和保持依赖的判断结果应该具有以下4种情况。 (1) 既具有无损连接性,又具有保持依赖性。 (2) 具有无损连接性,但不具有保持依赖性。 (3) 不具有无损连接性,但具有保持依赖性。 (4) 既不具有无损连接性,又不具有保持依赖性。 显然,符合要求的关系模式分解应是第(1)种情况。 5.5关系模式的规范化 在使用某种约束条件对关系模式进行规范化后,会使该关系模式变成一种规范化形式的关系模式,这种规范化形式的关系模式称为范式(Normal Form,NF)。根据规范化程度的不同,范式分为第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、“鲍依斯柯德”范式(BCNF)等。显然,最低级的范式是1NF。可以把范式的概念理解成符合某一条件的关系模式的集合,这样如果一个关系模式R为第x范式,就可以将其写成R∈xNF。 由于在判断一个关系模式属于第几范式时需要知道该关系模式的候选键,所以下面先介绍关系模式候选键的求解方法,再依次介绍各范式。 5.5.1候选键的求解方法 1. 关系属性的分类 定义5.10对于给定的关系模式S(U,F),关系S的属性按其在函数依赖的左端和右端出现分为以下4类。 (1) L类: 仅在F中的函数依赖左端(Left)出现的属性称为L类属性。 (2) R类: 仅在F中的函数依赖右端(Right)出现的属性称为R类属性。 (3) LR类: 在F中的函数依赖的左右两端都出现过的属性称为LR类属性。 (4) N类: 在F中的函数依赖的左右两端都未出现过的属性称为N类属性。 【例5.11】设有关系模式S(A,B,C,D)和S的函数依赖集F={A→C,B→AC,D→AC,BD→A},请指出关系S的属性分类。 解: 分析可知L属性有BD,R属性有C,LR属性有A。 2. 候选键的充分条件 定义5.11设有关系模式S(U,F)和属性集U={A1,A2,…,An}的子集X。 (1) 若X是R类属性,则X不是任一候选键的成员。 (2) 若X是N类属性,则X必包含在S的某一候选键中。 (3) 若X是L类属性,则X必为S的某一候选键的成员。 (4) 若X是L类属性,且X+包含了S的全部属性,则X必为S的唯一候选键。 (5) 若X是S的L类属性和N类属性组成的属性集,且X+包含了S的全部属性,则X是S的唯一候选键。 3. 多属性候选键的求解方法 算法5.3多属性候选键的判定算法。 输入: 关系模式R(A1,A2,…,An)和R的函数依赖集F。 输出: R的所有候选键。 方法: (1) 将关系模式R的所有属性分为L、R、N和LR 4类,并令X代表L和N类,Y代表LR类。 (2) 求X+F: 若X+F包含了关系模式R的全部属性,则X是R的唯一候选键,转(8)。 (3) 在Y中取一属性A,并求(XA)+F: 若(XA)+F包含了关系模式R的全部属性,则XA为R的一个候选键。 (4) 重复(3),直到Y中的属性依次取完为止。 (5) 从Y中去掉所有已成为主属性的属性A。 (6) 在剩余的属性中依次取两个属性、3个属性,……,将其记为集合B,并求(XB)+F: 若(XB)+F包含了关系模式R的全部属性,且自身不包含已求出的候选键,则XB为R的一个候选键。 (7)重复(6),直到Y中的属性按(6)的组合依次取完为止。 (8)输出候选键,算法结束。 【例5.12】设有关系模式R(A,B,C,D,E)和R的函数依赖集F={AB→C,C→D,D→B,D→E},求R的所有候选键。 解: 根据算法5.3 (1) 根据F对R的所有属性进行分类: A为L类属性; B、C、D均为LR类属性,并令Y=BCD; E为R类属性,没有N类属性。 (2) A+=A; A+不包含R的所有属性,所以A不是R的唯一候选键,但A为L属性,因此A必为R的候选键的成员。 (3) 从Y中取出一个属性B,求得(AB)+=ABCDE,(AB)+包含了R的全部属性,所以AB是R的一个候选键。 (4) 从Y中取出一个属性C,求得(AC)+=ABCDE,(AC)+包含了R的全部属性,所以AC是R的一个候选键。 (5) 从Y中取出一个属性D,求得(AD)+=ABCDE,(AD)+包含了R的全部属性,所以AD是R的一个候选键。 (6) 由于Y中的B、C、D均已经是主属性,不需要考察从Y中取3个属性的情况,候选键的求解到此结束。 综上可知,R的候选键有AB、AC和AD。 【例5.13】设有关系模式R(A,B,C,D,E)和R的函数依赖集F={A→BC,CD→E,B→D,E→A},求R的所有候选键。 解: 根据算法5.3 (1) 根据F对R的所有属性进行分类: A、B、C、D、E均为LR类属性,并令Y=ABCDE; 没有L类、R类和N类属性。 (2) 从Y中依次取一个属性,由于本例中没有L属性,所以仅需要计算从Y中取出的属性关于F的闭包。 A+=ABCDE,包含了R的全部属性,所以A为R的一个候选键。 B+=BD,没有包含R的全部属性,所以B不是R的候选键。 C+=C,没有包含R的全部属性,所以C不是R的候选键。 D+=D,没有包含R的全部属性,所以D不是R的候选键。 E+=ABCDE, 包含了R的全部属性,所以E为R的一个候选键。 (3) 从Y中去掉已经是候选键中的属性A和E,并令Y=BCD。 (4) 再从Y中依次取两个属性,并计算该属性集合关于Y的闭包。 (BC)+=ABCDE,包含了R的全部属性,所以BC为R的一个候选键。 (BD)+=BD,没有包含R的全部属性,所以BD不是R的候选键。 (CD)+=ABCDE,包含了R的全部属性,所以CD为R的一个候选键。 (5) 由于B、C、D也已经是主属性,不需要考察从Y中取3个属性的情况,候选键的求解到此结束。 综上可知,R的候选键有A、E、BC和CD。 5.5.2第一范式(1NF) 定义5.12如果关系模式R中每个属性的值域的值都是不可再分的最小数据单位,则称R为满足第一范式(1NF)的关系模式,也称R∈1NF。 当关系R的属性值域中的值都是不可再分的最小数据单位时,表示二维表格形式的关系中不再有子表。 为了与规范关系相区别,有时把某些属性有重复值(表中有子表)或空白值的二维表格称为非规范关系。图5.14给出了两个非规范关系。 图5.14非规范关系示例 对于有重复值的非规范关系,一般采用把重复值所在行的其他属性的值也予以重复的方法将其转换成规范关系。对于有空白值的非规范关系,由于目前的数据库管理系统支持“空值”处理功能,所以采用的方法是将空白值赋予空值标志(NULL)。图5.14的非规范关系对应的规范关系如图5.15所示。 图5.15图5.14的非规范关系转换成的规范关系 5.5.3第二范式(2NF) 1. 完全依赖 定义5.13设有关系模式R(U,F)和属性集U={A1,A2,…,An}的子集X、Y,如果X→Y,并且对于X的任何真子集X′都有X′→Y不成立,则称Y完全依赖于X,记为X→fY。 例如,如果有AB→C,且不存在A→C和B→C成立,则C完全依赖于AB。 【例5.14】在课程关系C(C#,CNAME,CLASSH)中有 {C#}→f{CNAME}、{C#}→f{CLASSH}和{C#}→f{CNAME,CLASSH}, 在学习关系SC(S#,C#,GRADE)中有{S#}→\{GRADE}、{C#}→\{GRADE}和{S#,C#}→f{GRADE}。 2. 部分依赖 定义5.14设有关系模式R(U,F)和属性集U={A1,A2,…,An}的子集X、Y,如果X→Y,但Y不完全依赖于X,则称Y部分依赖于X,记为X→pY。 例如,如果有AB→C,且至少存在A→C或B→C之一成立,则C部分依赖于AB。 比较定义5.13和定义5.14可知,所谓完全依赖,就是不存在X的真子集X′(X′ X,X′≠X)使X′→Y成立; 若存在X的真子集X′使X′→Y成立,则称为Y部分依赖于X。 同时,由定义5.13和定义5.14可知,当X是仅包含一个属性的属性子集时,Y都是完全依赖于X的,只有当X是由多个属性组成的属性子集时,才可能会有Y完全依赖于X和Y部分依赖于X两种情况。 3. 第二范式 定义5.15如果一个关系模式R属于1NF,并且它的每一个非主属性都完全依赖于它的一个候选键,则称R为满足第二范式(2NF)的关系模式,也称R∈2NF。 显然,如果一个关系模式R属于1NF,并且它的主键只由一个属性组成(单属性主键),不可能存在非主属性对候选键的部分依赖,所以R一定属于2NF。如果关系模式R的候选键是复合候选键(由多个属性组成的候选键),才可能出现非主属性部分依赖于候选键的情况。显然,如果在一个属于1NF的关系模式R中存在非主属性对候选键的部分依赖,则R不属于2NF。 【例5.15】对于图5.16所示的规范化关系SCT(S#,C#,GRADE,TNAME,TRSECTION)及其具体关系,该关系的主键为{S#, C#},表示在已知一个学号值和一个课程号值的情况下,就可以获知该学生学习该门课程的分数、(任课)教师名称及其所属的教研室。 图5.16一个关系模式SCT的具体关系 在假设一门课程只能由一位教师讲授的情况下,显然有C#→TNAME,即关系SCT的非主属性TNAME部分依赖于候选键{S#, C#},所以图5.16的关系SCT是1NF而不是2NF。然而,当把关系模式SCT分解成如图5.17所示的两个关系SC和CT时,SC和CT既是1NF,又是2NF。 图5.172NF关系 注意: 当一个关系模式不是2NF时会产生以下问题。 (1) 插入异常。例如,在上述的SCT关系模式中,当某一位新调来的教师还没有担任讲课任务时,无法登记他的所属教研室信息(TRSECTION)。因为在关系SCT中要插入新记录时必须给定主键的值,在没有担任讲课任务时,主键中的课程编号由于无法确定而无法插入。 (2) 删除异常。例如,在上述的SCT关系模式中,当某教师暂时不担任讲课任务时,如临时负责一段时间的实验室,该教师原来的讲课信息就要删掉,显然其他信息也就随着被删掉,从而造成了删除异常,即不应该删除的信息也被删掉。 (3) 数据冗余,修改异常。例如,在上述的SCT关系模式中,当某教师同时担任多门课程时,他的姓名和所属教研室信息要重复存储,造成大量的信息冗余。而且当教师的自身信息变化时,需要对数据库中所有相关的记录同时进行修改,造成修改的复杂化。如果漏掉一个记录,还会给数据库造成信息的不一致。 所以保证数据库中各关系模式属于2NF是数据库逻辑设计中的最低要求。 在一个1NF关系模式转换成2NF关系模式后,可以在一定程度上减少原1NF关系中存在的插入异常、删除异常、数据冗余等问题,但并不能完全消除该关系中的所有异常和数据冗余,于是需要进一步引入第三范式。 5.5.4第三范式(3NF) 1. 传递依赖 定义5.16设有关系模式R(U,F)和属性集U={A1,A2,…,An}的子集X、Y、Z,如果有X→Y,Y→Z,Z-Y≠,Z-X≠和Y→\X,则称Z传递依赖于X,记为X→tZ。 在定义5.16中,Z-Y≠说明在属性子集Z中至少存在一个属性不在属性子集Y中,因此保证了Y→Z是非平凡依赖。同理,Z-X≠说明在属性子集Z中至少存在一个属性不在属性子集X中,因此保证了X→Z是非平凡依赖。如果同时存在X→Y,Y→X,则有XY,而Y→\X保证了该定义中只有X→Y成立,XY不成立。 2. 第三范式 定义5.17如果一个关系模式R属于第一范式,并且R的任何一个非主属性都不传递依赖于它的任何一个候选键,则称R为满足第三范式的关系模式,也称R∈3NF。 【例5.16】设有关系模式SDR(S,I,D,M)和函数依赖集合F={SI→D,SD→M},关系SDR的唯一主键为SI,请分析SDR是第几范式。其中,S表示商店名,I表示商品,D表示商品部,M表示商品部经理。函数依赖SI→D表示每一个商店的每一个商品最多由一个商品部经销; SD→M表示每一个商店的每一个商品部只有一个经理。 解: 如果设X=SI,Y=SD,A=M。由SI→D,可得SI→SD,即X→Y和Y→A同时成立。这样就出现了非主属性(通过 )传递依赖于候选键,所以关系模式SDR不属于3NF。 但是在关系SDR中,既不存在非主属性D对候选键SI的部分依赖(D完全依赖于SI),也不存在非主属性M对候选键SI的部分依赖(即M不依赖于S,也不依赖于I),所以关系SDR属于2NF。 【例5.17】分析例5.15中由关系模式SCT分解成的两个关系模式SC(S#,C#,GRADE)和CT(C#,TNANE,TRSECTION)是第几范式。 解: 在关系模式SC中,因为非主属性GRADE既不部分依赖于S#或C#,也不传递依赖于{S#,C#},所以SC是3NF。 在关系模式CT中,有C#→TNAME和TNAME→TRSECTION,所以可推知C#→TRSECTION,即存在非主属性传递依赖于主键,所以CT不是3NF。由于不存在非主属性对候选键的部分依赖,所以CT是2NF。事实上,当某个教师主讲多门课程时,该教师所在的教研室信息要重复存储多次,即存在信息冗余。进一步,如果再把关系模式CT分解成CT1(C#,TNAME)和CT2(TNAME,TRSECTION),CT1和CT2就都是3NF。 定理5.5一个3NF的关系模式一定是2NF的。 证明: 用反证法。 设R是3NF的,但不是2NF的,那么一定存在非主属性A、候选键X和X的真子集Y,使得Y→A。由于A是非主属性,所以A―X≠,A―Y≠。由于Y是候选键X的真子集,所以X→Y,但Y→\X。这样在R上存在着非主属性A传递依赖于候选键X,所以R不是3NF的,这与假设矛盾,所以R也是2NF的。证毕。 可以证明,如果一个关系模式R是3NF,则它的每一个非主属性既不部分依赖于候选键,也不传递依赖于候选键。 【例5.18】图5.18(a)给出了一个是第二范式而不是第三范式的例子。该关系的主键为SUPPLIER,即供应商总部的名称,DISTANCE属性的值是供应商总部到一个城市的距离。CITY和DISTANCE都是非主属性,且都完全依赖于主键属性SUPPLIER,所以该关系是第二范式。 图5.182NF的规范化关系及其属性间的函数依赖 然而,如图5.18(b)所示,由于在该关系中存在SUPPLIER→CITY和CITY→DISTANCE,即非主属性传递依赖于主键,所以导致了供应商总部到城市的距离存储了不止一次的不良特性。 由图5.18(b)可知,该关系中存在的非主属性DISTANCE对主键SUPPLIER的传递依赖,又可以看作存在非主属性DISTANCE对非主属性CITY的函数依赖。所以,如果某关系存在非主属性对非主属性的函数依赖,该关系即为第二范式。 SUPPLIERS关系可以分解成两个第三范式的关系SUPPLIERS1和DISTANCE,如图5.19所示。 图5.19SUPPLIERS关系的分解 【例5.19】假设关系模式R的候选键都是单属性,请判断该关系模式的最高范式能达到第几范式。 解: 因为R的候选键都是单属性,所以一定不会存在非主属性对候选键的部分依赖,所以R满足2NF。本例提供的已知条件还无法确认函数依赖集F中是否存在非主属性对候选键的传递依赖,所以该关系模式的最高范式只能达到2NF。 【例5.20】全键属性的关系属于哪几范式?为什么? 解: 全键属性的关系同时属于1NF、2NF、3NF。 因为是全键关系,所以该关系中的属性都是主属性而不存在非主属性,也就不存在非主属性对键的部分函数依赖,所以属于2NF; 且不存在非主属性对键的传递函数依赖,所以全键关系也属于3NF。属于2NF和3NF的关系自然也属于1NF。 【例5.21】图5.2给出了大学教学信息管理数据库应用系统中的7个具有函数依赖约束的关系模式。由于其中的每个关系的函数依赖集中都只有一个函数依赖,显然不存在非主属性对候选键(主键)的部分依赖,也不存在非主属性对候选键(主键)的传递依赖,所以这7个关系都满足3NF,且保持无损和保持依赖。 5.5.5鲍依斯柯德范式 第三范式的关系消除了非主属性对主属性的部分依赖和传递依赖,解决了存储异常问题,基本上满足了实际应用的需求。但是在实际中还可能存在主属性间的部分依赖和传递依赖,同样会出现存储异常。 例如,在关系模式R(CITY,STREET,ZIP)中,R的候选键为{CITY,STREET}和{ZIP,STREET},R上的函数依赖集为F={{CITY,STREET}→ZIP,ZIP→CITY}。 R中没有非主属性,因此不存在非主属性对主属性的部分依赖和传递依赖,所以R是属于第三范式的。由于有ZIP→CITY,当选取{ZIP,STREET}为主键时,主属性间存在着部分函数依赖,会引起更新异常等问题。因此,针对此类问题提出了修正的第三范式,即鲍依斯柯德(BoyceCodd)范式,简称BCNF范式。 定义5.18设有关系模式R(U,F)和属性集U的子集X和A,且A\X,如果对于F中的每一个函数依赖X→A,X都是R的一个候选键,则称R是鲍依斯柯德范式,记为BCNF。 定义5.18说明,如果R属于BCNF,则R中的每一个函数依赖的决定因素都是候选键。进一步讲,R中所有可能的非平凡依赖都是一个或多个属性对不包含它们的候选键的函数依赖。 对于不是BCNF的关系模式,可通过模式分解使其成为BCNF。例如,当把关系模式R(CITY,STREET,ZIP)分解成R1(STREET,ZIP)和R2(ZIP,CITY)时,R1和R2都属于BCNF。 定理5.6一个BCNF的关系模式一定是3NF的。 证明: 用反证法。 设R是BCNF的,但不是3NF,那么必定存在非主属性A、候选键X、属性集Y,使得X→Y,Y→\X,Y→A,AY。但由于R是BCNF的,若有Y→A和AY,则必定有Y是R的候选键,因此应有Y→X,这与假设Y→\X矛盾。证毕。 与定理5.6的结论不同,关系模式R(CITY,STREET,ZIP)的例子说明,一个属于3NF的关系模式不一定属于BCNF。例如,对于关系模式SC(S#,C#,GRADE),不存在非主属性对候选键{S#,C#}的部分依赖和传递依赖,所以SC属于3NF。但是由于关系模式SC的函数依赖{S#,C#}→GRADE的被决定因素是非主属性,所以SC不属于BCNF。 5.5.6范式之间的关系和关系模式的规范化 1. 范式之间的关系 对于前面介绍的4种范式,就范式的规范化程度来说,因为BCNF一定是3NF,3NF一定是2NF,2NF一定是1NF,所以它们之间的关系满足1NF2NF3NFBCNF; 就对函数依赖的要求(消除程度)来说,它们之间的关系如下。 第一范式(1NF) ↓消除了非主属性对候选键的部分函数依赖 第二范式(2NF) ↓消除了非主属性对候选键的传递函数依赖 第三范式(3NF) ↓消除了主属性对候选键的部分函数依赖和传递函数依赖 鲍依斯柯德(BCNF) 通过比较可知,一个数据库模式中的关系模式如果都是BCNF,那么它消除了整个关系模式中的存储异常,在函数依赖范畴内达到了最大程度的分解。3NF的分解不彻底性表现在可能存在主属性对候选键的部分依赖和传递依赖。但是在大多数情况下,一个关系模式中既有主属性,又有非主属性,所以不会存在主属性对主属性的部分依赖和传递依赖,因此数据库模式中的关系模式都达到3NF一般就可以了。 2. 关系模式的规范化概念 为了把一个规范化程度较低(设为x范式)的关系模式转换成规范化程度较高(设为x+1范式)的关系模式,需要对规范化程度较低的关系模式进行分解。其分解过程要求满足保持原信息的无损和保持原来的函数依赖。这种通过模式分解使满足低一级范式的关系模式转换为满足高一级范式的关系模式的过程称为关系模式的规范化。 最后还需要说明的是,Beeri和Bernstein在1979年已经证明,仅确定一个关系模式是否为鲍依斯柯德范式就是一个NP完全性问题(一个问题的NP完全性几乎肯定地隐含了它的计算时间是指数级的),所以目前还很难找到比较好的像鲍依斯柯德范式的无损连接分解和保持依赖分解的算法。再加上实际中存在主属性间的部分依赖和传递依赖的情况比较少见,所以在目前的数据库模式设计中只考虑像3NF的保持无损连接和保持依赖分解就足够了。 5.6小结 关系模式的规范化设计就是按照函数依赖理论和范式理论对逻辑结构设计中第一步所设计的关系模式进行规范化设计,基本设计方法可归纳如下。 (1) 根据每个关系模式的内涵,从语义的角度分别确定每个关系模式中各属性之间的数据依赖,进而确定每个关系模式的函数依赖集。 (2) 求每个关系模式的函数依赖集的最小依赖集,即按照函数依赖理论中的最小依赖集的求法: 使每个关系模式的函数依赖集中没有多余依赖; 每个依赖的左端没有多余属性; 每个依赖的右端只有一个属性。 (3) 将求得的每个关系模式的函数依赖集中决定因素相同的函数依赖进行合并。例如,如果求得的最小依赖集为G={X→A,X→B,X→C,YZ→D,YZ→E},那么将其决定因素相同的函数依赖合并后的结果为G={X→ABC,YZ→DE}。 (4) 确定每个关系模式的候选键。 (5) 分析每个关系模式中存在的非主属性对候选键的部分依赖性和传递依赖性,确定其范式级别。 (6) 对不满足三范式的关系模式,按照关系模式分解理论和函数依赖理论,对每个关系模式及与之相关的函数依赖进行既保持无损连接性又保持函数依赖性的模式分解,直到所有关系模式都满足三范式为止。 (7) 通过以上模式分解过程后,可能会出现某些完全相同的关系模式,这一步要将完全相同的几个关系模式“合并”成一个单独的关系模式,即去掉多余的关系模式。 单选题 作业 习题5 51解释下列术语。 (1) 非平凡依赖(2) 函数依赖的逻辑蕴含 (3) 部分依赖(4) 完全依赖 (5) 无损连接分解(6) 保持函数依赖的分解 (7) 2NF(8) 3NF 52设有关系模式R(A,B,C,D,E,H),R的函数依赖集为F={A→D,E→C,AB→E,CD→H}。 (1) 当X=AE时,求X关于F的闭包X+。 (2) 当X=AB时,求X关于F的闭包X+。 53设有关系模式R(A,B,C,D,E),R的函数依赖集为F={A→D,E→D,D→B,BC→D,DC→A},求R的所有候选键。 54设有关系模式R(A,B,C,D,E),R的函数依赖集为F={AB→C,C→D,D→E},求R的所有候选键。 55设有关系模式R(A,B,C),R的函数依赖集为F={A→B,B→C},并有分解ρ={R1(AB),R2(BC)},判断分解ρ是否为无损连接分解。 56设有关系模式R(A,B,C),R的函数依赖集为F={AB→C,C→A},并有分解ρ={ R1(AC),R2(BC)},判断分解ρ是否具有无损连接性。 57设有关系模式R(A,B,C),R的函数依赖集为F={A→B,B→C},并有分解ρ={R1(AB),R2(BC)},判断分解ρ是否保持依赖性。 58设有关系模式R(A,B,C),R的函数依赖集为F={A→B,B→C},并有分解ρ={R1(AC),R2(BC)},判断分解ρ是否保持依赖性。 59设有关系模式R(A,B,C,D),其函数依赖集为F={D→A,C→D,B→C},判断R能达到第几范式。 510设有关系模式R(A,B,C,D),其函数依赖集为F={B→D,AB→C},判断R能达到第几范式。 511设有关系模式R(A,B,C,D,E,P),R的函数依赖集为F={A→B,C→P,E→A,CE→D},并有分解ρ={R1(ABE),R2(CDEP)},判断R1为第几范式。