《Database.System.Concepts》的8.3 Decomposition Using Functional Dependencies(P329~338)

8.3  使用函数依赖进行分解
    在8.1节中,我们知道存在一个规范方法判断一个关系模式是否应该分解。这个方法基于码和函数依赖的概念。
    在讨论关系数据库设计的算法时,我们需要针对任意的关系及其模式讨论,而不只是讨论例子。回想第2章对关系模型的介绍,我们在这里对我们的表示法进行概述。
----一般情况下,我们用希腊字母表示属性集(例如α)。我们用一个小写的罗马字母后面跟一个用一对圆括号括住的大写字母来指关系模式(例如r(R))。我们用表示法r(R)表示该模式是关系r的,R表示属性集,不过当我们不关心关系的名字时经常简化我们的表示法而只用R.
    当然,一个关系模式是一个属性集,但是并非所有的属性集都是模式。当使用一个小写的希腊字母时,我们是指一个有可能是模式也可能不是模式的属性集。当我们希望指明属性集一定为一个模式时,就使用罗马字母。
--当属性集是一个超码时,我们用K表示它。超码属于特殊的关系模式,因此我们使用术语“ K 是r(R)的超码"
--我们对关系使用小写的名字。在我们的例子中,这些名字是企图有实际含义的(例如 Instructor),而在我们的定义和算法中,我们使用单个字母,比如r.
--当然,一个关系在任意给定时间都有特定的值;我们将那看作一个实例并使用术语“ r的实例"。我们明显在讨论一个实例时,我们可以仅用关系的名字(例如r).
8.3.1  码和函数依赖

    一个数据库对现实世界中的一组实体和联系建模。在现实世界中,数据上通常存在各种约束(规则)。例如,在一个大学数据库中预计要保证的一些约束有:

--学生和教师通过他们的ID唯一标识。

--每个学生和教师只有一个名字。

--每个教师和学生只〈主要)关联一个系。
--每个系只有一个预算值,且只有一个关联的办公楼。
     一个关系的满足所有这种现实世界约束的实例,称为关系的合法实例(legal instance);在一个数据库的合法实例中所有关系实例都是合法实例。

     几种最常用的现实世界约束可以形式化地表示为码(超码、候选码以及主码) ,或属性的集合。在这里重新表述该定义如下:令r(R)是一个关系模式。R的子集K是r(R)的超码(superkey)的条件是:在关系r(R)的任意合法实例中,对于r的实例中的所有元组对t1和t2总满足,若t1=!t2,则t1[k]=!t2[k]也就是说,在关系r(R)的任意合法实例中没有两条元组在属性集K上可能具有相同的值。显然,如果r中没有两条元组在K上具有相同的值,那么在r中一个K值唯一标识一条元组。

     鉴于超码是能够唯一标识整条元组的属性集,函数依赖让我们可以表达唯一标识某些属性的值的约束。考虑一个关系模式r(R) ,令α∈R且β∈R.

--给定r(R)的一个实例,我们说这个实例满足(satisfy)函数依赖α→β的条件是:对实例中所有元组对t1和t2,若t1[α]=t2[α]则,则t1[β]=t2[β].

--如果在r(R)的每个合法实例中都满足函数依赖α→β,则我们说该函数依赖在模式r(R)上成立(hold).

    使用函数依赖这一概念,我们说如果函数依赖K→R在r(R)上成立,则K是r(R)的一个超码。也就是说,如果对于r(R)的每个合法实例,对于实例中每个元组对t1和t2,凡是t1[K]和t2[K],,总有t1[R]=t2[R](即t1=t2),则K是一个超码.

    函数依赖使我们可以表示不能用超码表示的约束。在8.1.2节中我们曾考虑模式:

    inst_dept(ID,name,salary,dept_name,building,budget)

    在该模式中函数依赖dept_name→budget成立,因为对于每个系(由dept_name唯一标识)都存在唯一的预算数额。
属性对(IDdept_name)构成inst_dept的一个超码,我们将这一事实记做:

                                                     ID,dept_name,salary,building,budget
我们将以两种方式使用函数依赖:
--判定关系的实例是否满足给定函数依赖集F.
--说明合法关系集上的约束。因此,我们将只关心满足给定函数依赖集的那些关系实例。如果我们希望只考虑模式R上满足函数依赖集F的关系,我们说F在r(R)上成立。

       让我们考虑图8·4中的关系r的实例,看看它满足什么函数依赖。注意到A→C是满足的。存在两条元组的值为a1。这些元组具有相同的C值,c2,类似地,A值为a2的两条元组具有相同的C值。没有其他元组对具有相同的A值。但是,函数依赖C→A是不满足的。为了说明这一点,考虑元组t1=(a2,b3,c2,d3)和元组t2 =(a3,b3,c2,d4)。这两条元组具有相同的C值,但它们具有不同的A值,分别为和。因此,我们找到一对元组t1和t2使得t1[C]=t2[C],但t1[A]=!t2[A].

     有些函数依赖称为平凡的(trivial)因为它们在所有关系中都满足。例如,A→A在所有包含属性的关系中满足。从字面上看函数依赖的定义,我们知道,对所有满足t1[A]=t2[A]的元组t1和t2,有t1[A]=t2[A].同样,AB→A也在所有包含属性A的关系中满足。一般地,如果β∈α,则形如α→β的函数依赖是平凡的。

重要的是,要认识到一个关系实例可能满足某些函数依赖,它们并不需要在关系的模式上成立.在图8-5的classroom关系的实例中,我们发现room_number→capacity是满足的。但是,我们相信,在现实世界中,不同建筑里的两个教室可以具有相同的房间号,但具有不同的空间大小。因此,有时有可能存在一个classroom关系的实例,不满足room_number→capacity.所以,我们不将room_number→capacity包含于classroom关系的模式上成立的函数依赖集中。然而,我们会期望函数依赖building,room_number→capacity在classroom模式上成立。
      给定关系r(R)上成立的函数依赖集F,有可能会推断出某些其他的函数依赖也一定在该关系上成立。例如,给定模式r(A,B,C) ,如果函数依赖A→B和B→C在r上成立,可以推出函数依赖A→C也一定在r上成立。这是因为,给定A的任意值,仅存在B的一个对应值,且对于B的那个值,只能存在C的一个对应值。我们稍后将在8.4.1节学习如何进行这种推导。
    我们将使用F+符号来表示F集合的闭包(closure) ,也就是能够从给定F集合推导出的所有函数依赖的集合。显然,F+包含F中所有的函数依赖。
8.3.2    Boyce-Codd范式
    我们能达到的较满意的范式之一是Boyce-Codd范式(Boyce-Codd Normal Form,BCNF)。它消除所有基于函数依赖能够发现的冗余,虽然,如我们将在8.6节中看到的,可能有其他类型的冗余还保留着。具有函数依赖集F的关系模式R属于BCNF的条件是,对F+中所有形如α→β的函数依赖(其中α∈β且β∈R),下面至少有一项成立:
---α∈β是平凡的函数依赖(即,β∈α)。
---α是模式R的一个超码。

一个数据库设计属于BCNF的条件是,构成该设计的关系模式集中的每个模式都属于BCNFO

我们已经在8.1节中见过了不属于BCNF的关系模式的例子:

    inst_dept(ID,name,salary,dept_name,building,budget)

函数依赖dept_name→budget在inst_dept上成立,但是dept_name并不是超码(因为一个系可以有多个不同的教师)。在8.1.2节中,我们看到把inst_dept分解为instructor和department是一个更好的设计。
模式instructor属于BCNF.所有成立的非平凡的函数依赖,例如:
                                                      ID →name,dept_name,salary
在箭头的左侧包含ID,且ID是instructor的一个超码(事实上,在这个例子中,是主码)。(也就是说,在不包含ID的另一侧上,对于name、dept_name和salary的任意组合不存在非平凡的函数依赖.)因此,department属于BCNF.
类似地,-“模式属于BCNF,因为所有成立的非平凡函数依赖,例如:
                   dept_name→building,budget
在箭头的左侧包含dept_name,且dept_name是department的一个超码(和主码)。因此,department属于BCNF.
     我们现在讲述分解不属于BCNF的模式的一般规则。设R为不属于BCNF的一个模式。则存在至少一个非平凡的函数依赖α→β,其中α不是R的超码。我们在设计中用以下两个模式取代R:

--(α∪β)

--(R-(β-α))

在上面的inst_dept例子中,α=dept_name,β={building,budget},且inst_dept被取代为:

--(α∪β)=(dept_name,building,budget)
--(R-(β-α))=(ID,name,dept_name,salary)
在这个例子中,结果β-α=β是彘我们需要像上述那样的表述规则,从而正确处理箭头两边都出现的属性的函数依赖。技术上的原因我们会在8.5.1节介绍。
当我们分解不属于BCNF的模式时,产生的模式中可能有一个或多个不属于BCNF.在这种情况中,需要进一步分解,其最终结果是一个BCNF模式集合。
8· 3· 3 BCNF和保持铱赖
    我们已经看到多种表达数据库一致性约束的方式:主码约束、函数依赖、check约束、断言和触发器。在每次数据库更新时检查这些约束的开销很大,因此,将数据库设计成能够高效地检查约束是很有用的。特别地,如果函数依赖的检验仅需要考虑一个关系就可以完成,那么检查这种约束的开销就很低。我们将看到,在有些情况下,到BCNF的分解会妨碍对某些函数依轅的高效检查。
    对此举例,假定我们对我们的大学机构做一个小的改动。在图7 ·巧的设计中,一位学生只能有一位导师。这是由从student到advisor的联系集advisor为多对一而推断出的。我们要做的“小"改动是一个教师只能和单个系关联,且一个学生可以有多个导师,但是一个给定的系中至多一位。
    利用E-R设计实现这个改动的一种方法是,把联系集advisor替换为涉及实体集instructor,student
和department的三元联系集dept_advisor,它是从多对一的,如图8.6 所示。该E-R图指明了“一个学生可以有多位导师,但是对应于一个给定的系最多只有一个"的约束。
   对应于新的E-R图,instructor、department和student的模式没有变。然而,从dept_advisor导出的模式现在为:
                            dept_advisor(s_ID,dept_name)
虽然没有在E-R图中指明,不过假定我们有附加的约束“一位教师只能在一个系担任导师。"
那么,下面的函数依赖在dept_advisor上成立:

                                                           s-ID→dept_name

                                                           s_ID,dept_name→i_ID  

第一个函数依赖产生于我们的需求“一位教师只能在一个系担任导师"。第二个函数依赖产生于我们的需求“对于一个给定的系,一个学生可以有至多一位导师'

注意,在这种设计中,每次一名教师参与一个dept_advisor联系的时候,我们都不得不重复一次系的名称。我们看到dept_advisor不属于BCNF,因为i_ID不是超码。根据BCNF分解规则,得到:

(s_ID,i_ID)

(i_ID,dept_name)

上面的两个模式都属于BCNF。(事实上,你可以验证,按照定义任何只包含两个属性的模式都属于 BCNF)然而注意,在BCNF设计中,没有一个模式包含函数依赖s_ID,dept_name→i_ID中出现的所有属性。
由于我们的设计使得该函数依赖的强制实施在计算上很困难,因此我们称我们的设计不是保持依赖的(dependency preserving)。由于常常希望保持依赖,因此我们考虑另外一种比BCNF弱的范式,它允许我们保持依赖。该范式称为第三范式。 
8 · 3· 4第三范式
BCNF要求所有非平凡函数依赖都形如α→β,其中α为一个超码。第三范式(3NF)稍微放宽了这个约束,它允许左侧不是超码的某些非平凡函数依赖。在定义3NF之前,我们回想到候选码是最小的超码一一任何真子集都不是超码的超码。

具有函数依赖集F的关系模式R属于第三范式(third normal form)的条件是:对于F+中所有形如α→β的函数依赖(其中a∈R且β∈R),以下至少一项成立:

--α→β是一个平凡的函数依赖。

--α是R的一个超码
--β-α中的每个属性A都包含于R的一个候选码中
注意上面的第三个条件并没有说单个候选码必须包含β-α中的所有属性;β-α中的每个属性A可能包含于不同的候选码中。
    前两个条件与BCNF定义中的两个条件相同。3NF定义中的第三个条件看起来很不直观,并且它的用途也不是显而易见的。在某种意义上,它代表BCNF条件的最小放宽,以确保每一个模式都有保持依赖的3NF分解。它的用途在后面介绍3分解时会变得更清楚。
    注意任何满足BCNF的模式也满足3NF,因为它的每个函数依赖都将满足前两个条件中的一条。所以BCNF是比3NF更严格的范式。
    3NF的定义允许某些BCNF中不允许的函数依赖。只满足3NF定义中第三个条件的依赖α→β在BCNF中是不允许的,但在3NF中是允许的.

    现在我们再次考虑联系集dept_advisor,它具有以下函数依赖:

                                                                   i_ID→dept_name

                                                                   s_ID,dept_name→i_ID

    在8.3.3节中我们说函数依赖“  i_ID→dept_name"导致dept_advisor模式不属于BCNF.注意这里α=i_ID,β=dept_name,并且β-α=dept_name.由于函数依赖s_ID,dept_name在dept_advisor上成立,于是属性dept_name包含于一个候选码中,因此dept_advisor属于3NF.
       我们已经看到,当不存在保持依赖的BCNF设计时,必须在BCNF和3NF之间进行权衡。这些权衡将在8.5.4节详细讨论。
8.3.5    更高的范式

    在某些情况中,使用函数依赖分解模式可能不足以避免不必要的信息重复。考虑在instructor实体集定义中的小变化,我们为每个教师记录一组孩子名字以及一组电话号码。电话号码可以被多个人共享。因此,phone_number和child_name将是多值属性,并且根据我们从E-R设计生成模式的规则,我们会有两个模式,多值属性phone_number和child_name中每个属性对应一个模式:             (ID,child_name)

                       (ID,phone_number)

如果我们合并这些模式而得到

                        (ID,child_name,phone_number)
我们会发现该结果属于BCNF,因为只有平凡的函数依赖成立。因此我们可能认为这样的合并是个好主意。然而,通过考虑有两个孩子和两个电话号码的教师的例子,我们会发现这样的合并是一个坏主意。例如,令ID为99999的教师有两个孩子,叫作"David"和"William",以及有两个电话号码,512-555-12和512-555-4321。在合并的模式中,我们必须为每个家属重复一次电话号码:
 (99999,David,512-555-1234)
(99999,David, 512-555-4321)
(99999, William,512一555一1234)
(99999,William,512一555一4321)
如果我们不重复电话号码,且只存储第一条和最后一条元组,我们就记录了家属名字和电话号码,
但是结果元组将暗指David对应于512一555一1234,而William对应于512一555一4321。我们知道,这是不正确的。
由于基于函数依赖的范式并不足以处理这样的情况,因此定义了另外的依赖和范式。我们在8.6和8.7节对此进行讲述。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值