
1.6 关系的规范化
在关系数据库中,对于同一个问题,选用不同关系模式集合作为数据库模式,其性能的优劣是大不相同的,某些数据库模式设计常常带来存储异常,这是不利于实际应用的。为了区分数据库模式的优劣,人们常常把关系模式分为各种不同等级的范式(Normal Form)。
在关系规范化中,通常将关系模式分为5个级别,即5种范式。满足最低条件的称为第一范式,简称1NF。1NF是关系模式应满足的最起码的条件。在第一范式基础上进一步满足一些要求的可升级为第二范式,其余依次类推。通常关系模式R是第X范式就写成R∈XNF。
一个低一级范式的关系模式,通过分解可以转换为若干个高一级范式的关系模式,这种过程称为关系的规范化。关系的规范化主要目的是解决数据库中数据冗余、插入异常、删除异常和更新异常等数据存储问题。例如,关系模式SCD(学号,姓名,课程名,成绩,教师名,教师职称)中,有多少学生学习了某门课程就必须重复输入多少次教师名和教师职称,因此存在数据冗余问题;如果要插入刘老师的个人信息,但刘老师未开课,会造成无法插入主键“学号+课程名”,因此存在插入异常问题;当要删除某门课程,如:课程名=“数据库技术”的元组时,会丢失相关任课教师的信息,因此存在删除异常;当要更改某个学生的姓名时,则必须搜索出包含该姓名的每个元组,并对其姓名逐一修改,这样修改量大,容易造成数据的不一致问题,因此存在更新异常。
关系规范化的基本方法是逐步消除关系模式中不合适的数据依赖,使关系模式达到某种程度的分离,也就是说,不要将若干事物混在一起,而要彼此分开,用一个关系表示一事或一物,所以,规范化的过程也被认为是“单一化”的过程。
规范化是以函数相关性理论为基础的,其中最重要的是函数(数据)依赖,定义如下:给定一个关系模式R,有属性(或属性组)A和B,如果R中B的每个值都与A的唯一确定值对应,则称B函数依赖于A,A被称为决定因素。
1.6.1 第一范式(1NF)
设R是一个关系模式,如果R中的每个属性都是不可分解的,则称R是第一范式,记为R∈1NF。
第一范式要求不能表中套表。它是关系模式最基本的要求,数据库模式中的所有关系模式必须是第一范式。关于第一范式这个问题,在前面曾经给过一个例子,这里再给出如表1-14所示选修关系SC1,以此说明非第一范式的弊病。
该选修关系SC1不是1NF,因为其课程名中包含了若干门课程,是可以分解为若干单门课程的。对于这样的关系模式,如果要修改某个学生的选课情况,就要涉及该学生原来的所有课程名,这是很不方便的。为了避免这样的问题,可以将选修关系SC1的课程名属性拆开,形成如表1-15所示SC2关系形式,显然,SC2∈1NF。
表1-14 SC1
表1-15 SC2
1.6.2 第二范式(2NF)
如果关系模式R是第一范式,且每个非键属性都完全依赖于键属性,则称R是第二范式,记为R∈2NF。
部分函数依赖关系是造成插入异常的原因。在第二范式中,不存在非键属性对键属性的部分函数依赖关系,因此第二范式解决了插入异常问题。
例如,关系模式SCD(学号,姓名,课程名,成绩,系名,系主任),它不是第二范式。因为该关系模式的键是学号+课程名,对于非键属性姓名和系名来说,它们只依赖于学号,而与课程名无关。解决的办法是将非第二范式的关系模式分解出若干个第二范式关系模式。分解的方法如下:
(1)把关系模式中对键完全函数依赖的非主属性与决定它们的键放在一个关系模式中;
(2)把对键部分函数依赖的非主属性和决定它们的主属性放在一个关系模式中;
(3)检查分解后的新模式,如果仍不是2NF,则继续按照前面的方法进行分解,直到达到要求。
对于关系模式SCD来说,成绩属性完全函数依赖键学号+课程名,可将它们放在一个关系模式中。属性姓名、系名、系主任只依赖学号,可将它们放在另一个关系模式中。得到的分解结果如下:
学生和系关系模式:SD(学号,姓名,系名,系主任)
选修关系模式:SC(学号,课程名,成绩)
这两个关系模式都不存在部分函数依赖,它们都是第二范式。虽然消除了数据的插入异常,但仍然存在其他存储问题,关系模式SD包含了学生和系两方面的信息,该模式仍然存在问题,有待进一步分解。这就需要更高级别的范式。
1.6.3 第三范式(3NF)
如果关系模式R是第二范式,且没有一个非键属性传递依赖于键,则称R是第三范式,记为R∈3NF。
传递函数依赖关系是造成删除异常的原因。第三范式消除了传递函数依赖,因此解决了数据的删除异常问题。
例如,关系模式SD(学号,姓名,系名,系主任)是上例的分解结果,它仍然存在问题。该关系模式中存在着学号→系名,系名→系主任,即系主任传递依赖于学号,因此关系模式SD不是第三范式,它存在删除异常问题。解决的办法就是消除其中的传递依赖,将关系模式SD进一步分解为若干个独立的第三范式模式。分解的方法如下:
(1)把直接对键函数依赖的非主属性与决定它们的键放在一个关系模式中;
(2)把造成传递函数依赖的决定因素连同被它们决定的属性放在一个关系模式中;
(3)检查分解后的新模式,如果不是3NF,则继续按照前面的方法进行分解,直到达到要求。
对于关系模式SD来说,姓名、系名直接依赖主属性学号,可将它们放在一个关系模式中。系名决定系主任,系名是造成传递函数依赖的决定因素,将它们放在另一个关系模式中。得到的分解结果如下:
学生关系模式:S(学号,姓名,系名)
系关系模式:D(系名,系主任)
可以看出,S和D关系模式各自描述单一的现实事物,都不存在传递依赖关系,它们都是第三范式。
一个关系模式达到3NF,基本解决了异常问题,但还不能彻底解决数据冗余问题。因为3NF不能很好地处理模型中含有多个候选键和候选键是组合项的情况,因此需要更高级别的范式。
【课堂练习4】假设某商业集团数据库中有1个关系模式R(商店编号,商品编号,数量,部门编号,负责人),如果规定:每个商店的每种商品只在一个部门销售;每个商店的每个部门只有一个负责人;每个商店的每种商品只有一个库存数量。
(1)写出关系模式R的基本函数依赖集。
(2)找出关系模式R的候选码。
(3)关系模式R最高已经达到第几范式?为什么?
(4)如果R不属于3NF,请将R分解成3NF。
1.6.4 Boyce-Codd范式(BCNF)
BCNF范式也称为扩充的第三范式或增强第三范式。
如果关系模式R中的所有决定因素都是键,则称R是BCNF范式。BCNF范式消除了关系中冗余的键,由BCNF范式的定义,可以得到以下结论:
①所有非主属性对每个键完全函数依赖。
②所有主属性对每个不包含它的键完全函数依赖。
③没有任何属性完全函数依赖于非键的任何一组属性。
可以证明,若R是BCNF范式,则肯定是3NF。但若R是3NF,则不一定是BCNF范式。
例如:学生关系模式S(学号,姓名,系名)不仅是3NF,还是BCNF范式。
分两种情况进行分析。一种情况假设姓名可以有重名,则学号是该模型唯一决定因素,它又是键,所以关系模式S是BCNF范式。另一种情况假设姓名没有重名,则学号、姓名都是候选键,且除候选键以外,该模型没有其他决定因素,所以关系模式S仍是BCNF范式。
例如:设有关系模式STJ(学生,教师,课程),并有如下假设:
①每位教师只教一门课程;
②一门课程由多位教师讲授;
③对于每门课,每个学生的讲课教师只有一位。
关系模式STJ是3NF,但不是BCNF范式。
分析如下:由语义可知,关系模式STJ具有的函数依赖:(学生,课程)→教师,教师→课程,(学生,教师)→课程,如图1-11所示。
图1-11 非BCNF实例
关系模式STJ有两个候选键(学生,课程)和(学生,教师),由于没有任何非主属性对键传递依赖或部分依赖,所以模式STJ是3NF。但它不是BCNF范式,因为教师决定课程,教师是课程的决定因素,而教师这一单一属性不是键,因此,模式STJ不是BCNF范式。
可以将模式STJ分解两个关系模式,它们是ST(学生,教师)和TJ(教师,课程)。
将3NF分解为BCNF范式的方法如下:
①在3NF关系模式中,去掉一些主属性,只保留主键,使它们只有唯一的候选键;
②把去掉的主属性,分别同各自的非主属性组成新的关系模式;
③检查分解后的新模式,如果仍不是BCNF,则继续按照前面的方法进行分解,直到达到要求。
在数据库设计中,以达到3NF作为主要目标。当然能够达到BCNF更好,但从理论上说,达到BCNF有时会破坏原来关系模式的一些固有特点。
例如,设有关系模式R(U),U属性由属性S、T和V构成,存在的函数依赖有(S,T)→V,V→S。
可以验证,该模型是3NF,但不是BCNF。无论将R如何分解,将损失函数依赖(S,T)→V。
纵观4种范式,可以发现它们之间存在着如下的关系:
BCNF⊆3NF⊆2NF⊆1NF
从范式所允许的函数依赖方面进行比较,它们之间有如图1-12所示的关系。
一般情况下,没有异常弊病的数据库设计是好的数据库设计,一个不好的关系模式也总是可以通过分解转换成好的关系模式的集合。但是在分解时要全面衡量,综合考虑,视实际情况而定。对于那些只要求查询而不要求插入、删除等操作的系统,几种异常现象的存在并不影响数据库的操作。这时便不宜过度分解,否则当要对整体查询时,需要更多的多表连接操作,这有可能得不偿失。
在实际应用中,最有价值的是3NF和BCNF,在进行关系模式的设计时,通常分解到3NF就足够了。
图1-124 种范式的比较