`

关于多值依赖--范式!

阅读更多
原文
http://book.csdn.net/bookfiles/1168/100116834872.shtml
.6 实体中的多值依赖

在本节中,我们会看看下一个层次的规范化。虽然在考虑了实现规范化上所需投入的时间,以及最终数据库的性能开销后,这个层次的规范化并没有被普遍采用,然而,本节和这之前的部分一样绝对重要。

在前面的部分中,我们处理的是属性的结构以及非键属性和键之间的关系。接下来将要讨论的两个范式处理的仍然是非键属性间的关系,但是,现在我们处理的是关系的基数,以及当基数大于一时可能引发的各种问题。

虽然第三范式通常被认为是正确的数据库设计的巅峰,然而,在逻辑设计中,仍然可能留下了一些严重的问题。说得更具体些,本节的范式要处理的是属性之间的多值关系和依赖情况。为此,我们将首先较详细地研究第四范式,然后简单地介绍第五范式。

4.6.1 第四范式

到目前为止,我们的规范化原则处理的都是实体中列之间的冗余。我们没有解决的问题是:如果实体有组合键,而键中的一列或多列仍然持有冗余数据,则会引发若干问题。实体规范化的第四范式讲的就是这些问题。在简单情况下,朝着第四范式前进要解决的是类似于这样的问题:建立模型,将实际情况下需要多值的属性存储为单一值。要解决的第二类问题更加不易把握,因为它处理的是三元关系,以及如何将其分解为更易处理的、更小的表。

为了便于说明,考虑一个将学生分配到班级的实体,同时,我们想要表示每个班级每个学生的老师。因此,我们将老师和学生放到如图4-26所示的ClassAssignment实体中。

这样做看起来很不错,并且,由于展示ClassAssignment实例需要所有的属性,这可以说是个最优的解决方案。然而,进一步的考虑发现这个实体并不让人满意。如果我们现在想要改变一个班级的老师,将不得不对班级中的所有学生实例进行修改,因为每个ClassAssignment实例都包括了班级和老师。

很明显,这样做不是最好的,因为规范化最主要的一点就是消除冗余信息,尤其是消除修改一条信息需要在若干地方修改这条信息的情况。注意到一个班级有若干学生,一名学生可以在若干个班级中,以及共有若干位老师这个事实,可以找到一个简单的解决方案。(我还将一步步地展示一个讲同样问题的例子,教会你如何在不是立刻就有思路的情况下寻找到解决方案。)

为了实现新的解决方案,我们创建3张表:一张针对班级,其他两张分别体现老师与班级的关系以及学生与班级的关系。如图4-27所示显示了修改后的设计。



图4-27 修改后的班级模型

之所以可以这样变形,关键在于学生和老师之间的关系(至少就班级分配来说)是完全围绕着班级进行的。因此,我们不需要体现Student和Teacher实体之间的关系。通过Class实体进行联结,可以得到有关哪个学生由哪个老师授的信息。

这类变形在很大程度上是第四范式要做的事。我们必须打破这种三元关系,将其变为没有冗余信息的更有用的形式。

实体要满足第四范式,必须满足下列条件。

l 实体必须满足BCNF:该条件保证所有键都被恰当地定义了,并且,实体中所有的值都正确地依赖于实体的键。

l 在一个属性与实体的键之间,多值依赖(MVD)必须不能超过一个:能够存储多值,并且与实体的键相关联的属性不能超过一个,否则会出现重复的数据。另外,我们应该保证,对多值属性的每个值,都不会在单值属性中重复它。

看一些例子会有助于弄清楚以上的想法。让我们先看看违反第四范式主要的3种形式:

l 三元关系;

l 潜伏的多值属性;

l 临时数据或历史值。

从我自己的观点来看,理解第四范式非常关键。要遵守第四范式的方法也相当简单。认为第三范式之后的范式没有意义的观点中,存在着一些重大的误解。一旦你明白了在第四范式的级别上规范化的意义,你就再也不会忽略第四范式所代表的内容。

1. 三元关系

在第1章我们简单地看过三元关系。通常,在真实环境下,关系不会表现为简单的二元类型,三元甚至三元以上的关系都很常见。只要我们在键中的任何地方看到了3个(或更多)识别性的或强制的非识别性关系,我们就有可能碰到麻烦(同时,要考虑到三元关系也许是挑选的键不够好造成的)。

考虑我们设计出一套实体来支持会议安排的情况,我们存储了有关会议、发言人以及举行会议所在的房间的信息。

让我们假设需要遵循如下的业务规则集合:

l 一场演讲可以安排多位发言人;

l 一场演讲可以安排在多个房间。

图4-28建模的关系是“发言人—在房间中—的会议上—发言”。


图4-28 “发言人—在房间中—的会议上—发言”关系

这些实体每一个都是BCNF实体。然而,3个实体间的关系很麻烦,因为键包含了3列,尤其是所有的属性都是从其他实体迁移而来。当然,这样做也可能一点错都没有,但是,任何时候发生了类似于这样的情况时,都需要进行一些调查,确保在我们的数据中没有多值依赖,因为它们最终可能会造成问题。

考虑每个会议都同时开展的情况。此时表中需要会议的时间,而这会使情况更为复杂。在这个时候,我们处理的是所有的会议都用一个会议时间的情况。让我们看一组示例数据(我们将房间、发言人和会议联结了起来,这样就能看到自然键)。



第一行没有问题,因为我们这一行是针对会议101,有一个发言人Davidson,在房间River Room中。接下来两行问题开始变得明显起来,因为会议202在一个房间中有两个不同的发言人。这迫使我们在“Room”属性中不必要地重复数据,因为我们现在已经存储了两条会议202是在Stream Room中的信息。如果会议改地方,我们就必须在两处都变更信息,如果我们忘记了这一点,基于目前没显示出来的某个值更新房间信息(比如,通过使用人工键),那我们最终就会得到如下的值。

在这个例子中,我们有重复的“Session”和“Room”属性数据,并且“404”会议有重复的“Session”和“Presenter”数据。当添加或修改数据时,这种数据复制造成的真正的问题就来了。如果我们想要更新Davidson和Hazel在Stream Room中进行发言的“Session”号,则需要修改两行。同样地,如果“Room”分配发生了变化,也有好几行必须修改。

当用这种方式实现实体时,也许不会像这里看到的那样,所有的行的所有列都填满了。接下来,我们会介绍一系列未填满的行,从功能上讲,它们与前面的实体集是等价的。


在这个例子中,有的房间值为null,有的发言人值也为null。我们消除了重复的数据,但现在我们有一些看起来怪里怪气的数据,到处都是null。不仅如此,我们现在不能用null来清楚地表达“我们还不知道会议的发言人是谁”的情况了。我们确实存储了与前面的例子等价的数据集,但是,这些数据的格式让人很难操作。姑且不论这样做是对是错,你也许可以立刻看出这样的数据操作起来是多么地让人烦恼。

为开发一个该问题的解决方案,让我们首先将Presenter作为主要的实体,如图4-29所示。

图4-29 Presenter是主要的实体

然后我们将RoomSessionPresenter实体分解为3个实体,如图4-30所示。

图4-30 以发言人为中心重新组织数据

这显然不是个正确的解决方案,因为除非被分配一个发言人,否则我们永远都不可能决定会议在哪个房间中举行。并且,Davidson在River Room和Stream Room中都有会议,但没有什么内容能够链接回去,告诉我们房间中举行的会议是什么。当我们分解关系时,如果我们丢失了数据的意义,这种分解就被称为有损分解。这里的情况就是有损分解,因此它并不是问题的合理解决方案。

接下来我们尝试着以会议举行的房间为中心,如图4-31所示。

图4-31 现在Room是主要的实体

将数据分解入实体中,如图4-32所示。

图4-32 以Room为中心重新组织数据

这也是个有损分解,例如,我们不能决定到底是谁在202会议上发言。它在Stream Room房间中,并且Davidson、Hazel和Hawkins都要在Stream Room中发言,但是,他们并不都在202会议上发言。所以,再一次,我们要考虑其他的设计。这一次,我们的设计以要举行的会议为中心,如图4-33所示。

看看图4-34中的数据。

最终,我们找对了该问题的解决方案。从这个数据出发,我们可以准确地决定谁在哪个房间、在哪个会议上发言,并且,添加或删除发言人,或甚至是修改房间都没有问题。拿404会议举例。对于404会议,在如下的结果集中,实体SessionRoom和SessionPresenter包含的数据是:


图4-33 现在Session是主要的实体

图4-34 以会议为中心重新组织数据


要向名单中加入一个名叫Evans的发言人,我们只需简单地加入另一行:


现在,这是个恰当的分解,不会有在先前的实体中所碰到的问题。我们现在有与发言人分开的会议集,在外键值中也不再需要null,因为如果我们想要表示一个房间没有被选中开会,我们就不创建SessionRoom实例。如果我们没有选中一名发言人也同样如此。更重要的是,现在我们为一个会议设定多个房间也不会有什么混乱。

如果需要用其他数据来扩展SessionPresenter这个概念,例如,指定一个备选发言人(或者是第一发言人和第二发言人),现在就有一个明确而合乎逻辑的地方来存储这些信息了。请注意,如果我们曾经试图在原来的实体中存储这些信息,那就会违反BCNF,因为AlternatePresenter属性只会与Session和Presenter有关系,与Room无关。

这个过程的关键是寻找属性之间的关系。对这个例子来说,会议和谁在会议上发言之间有关系,会议和会议的举行地点也有关系。反过来说,发言人与会议在哪里举行之间却没有直接的联系。

2. 潜伏的多值属性

我之所以使用“潜伏的”这个词,是因为粗看起来,在本节讨论的属性并不总会出问题。问题在于,某个属性在很多情况下看起来似乎需要的都仅仅是单值,但是,当仔细琢磨这个问题时,会发现其也有需要多值的时候。为了展示这层意思,让我们看看如图4-35的设计模型。

当我们考虑Contact实体时,问题浮出了水面。我们有3个属性:联系人的名字(假设这个名字满足第一范式)、电话号码和地址。名字没什么问题,因为所有的联系人都有一个用来代表他们自己的名字,问题在于,在这个时代,许多人都有不止一个地址和电话号码。所以我们就有了多值属性,需要进一步规范化来解决这个问题。为了允许多值的地址和电话号码,我们可以像图4-36那样修改设计。
[img]
http://dl.iteye.com/upload/picture/pic/64071/b4ed6d4e-b800-33be-bbaa-fa20d3a3aa4e.jpg[/img]
图4-35 包含了潜伏的多值属性的设计

图4-36 模型现在支持多值的地址和电话号码

虽然有多值的电话号码并没有违反第一范式(因为它们都是不同类型的电话号码,而不是同一类型的多个值),然而,它确实给我们带来了更多问题。因为我们只是简单地在属性名上添加了属性的类型(例如,HomeAddressId、FaxPhoneId),所以,如果用户有两个传真号或两个手机号,我们将面临更严重的多值属性问题。不仅如此,当属性的值不存在时,对每个属性我们都需要多个可以为null的值,这种情况当然很不理想,因为从技术上来说,null表示值未知,而不是值不存在。

这样表示关系真是一团糟。例如,如果客户需要对一位联系人增加其配偶的办公室电话号码属性,我们就必须修改模型,而这非常可能需要重写应用程序的代码。

让我们进一步修改设计,将Contact与ContactInformation实体分开,如图4-37所示。

Type属性表明我们存储在实例中的联系人信息的类型,如此一来,我们就可以将某个ContactInformation实例冠以“家庭”(Home)的“类型”(Type),为其附上地址和电话号码。通过这种方式,用户需要多少电话号码和地址,我们就可以加上多少。然而,由于地址和电话号码保存在同一张表中,如果联系人家庭地址和电话号码的数量不同,我们就还是需要在某些值中填入null。

图4-37 分开Contact和ContactInformation实体

在这个阶段,我们需要决定自己想要如何进行下去。我们可能想要一个电话号码与地址关联起来(例如,将家庭电话号码与家庭地址相关联)。就这个例子而言,我们将把ContactInformation实体分解为ContactAddress和ContactPhone(虽然这并不是该问题唯一可能的解决方案),如图4-38所示。

图4-38 用ContactAddress和ContactPhone实体来体现联系人的信息

这个修改消除了残留的多值依赖,因为现在我们可以有许多彼此独立的地址和电话号码,并且,我们可以想定义多少类型就定义多少类型,不需要修改实体的结构。然而,我们还可以再进一步:在逻辑模型中将电话号码和地址建模为不同的实体,再针对Type列加入域实体。这样做之后,我们就可以防止当用户想输入的是“Home”时,却输入 “Some”、“Homer”、“Hume”这样的值。将电话号码和地址建模为不同的实体,还使得我们能够建立用户可配置的约束,这样就可以不修改模型就加入新的类型。我们将在域实体上加入Description属性,它使我们可以说明一个类型的真实用途。Description属性使得我们可以处理如下情况:对一个组织来说,“离开”这种地址类型的意义可能很明白,但对于第一次使用系统的用户来说,其意义却很费解。针对这个类型,我们可以加入说明信息,比如“联系人出差延期,仍然在商务旅行中时的地址”。图4-39显示了我们最终的模型。

图4-39 最终模型

注意,我把添加的Address和PhoneNumber属性设置为替代键,为的是避免每次需要在系统中使用它们时都得设置一个重复的地址。通过这种方式,当我们有5个联系人有相同的办公室地址时,我们就只用修改一个值。在最终的实现中,这也许是所期望的东西,也许不是,因为它会增加复杂性;从商业的角度来看,增加这种复杂性也许值得,也许不值得。

事实上,在检查第一范式、第二范式、第三范式或Boyce-Codd范式时,你往往会发现很多这类问题。例如,回头想想讲第一范式时的Payment1、Payment2等,如果这个字段仅仅是Payment,它看起来会那么扎眼吗?也许不会。如果你在搜索实体时非常严格,并且意识到了支付是某种独立于客户的东西,那么你才有可能做对,否则就很容易忽略它。

范式的定义图



分享到:
评论
1 楼 heming_way 2012-03-31  
谢谢,对我很有用,解答了我对多值依赖的疑问

相关推荐

    关系型数据库---第一范式

    第一范式(1NF)是关系型数据库设计理论中的一种规则,要求每个字段都是原子型的,表格没有多值项目和重复组,并且每个字段都有一个关键字(key)。 在关系型数据库中,第一范式的应用是非常重要的,因为它可以确保...

    数据库范式5nf-第四范式(4NF)数据库管理系统.pdf

    例如,如果有两个属性A和B,当A的值确定时,B可能有多个相关的值,这便构成了多值依赖。在4NF中,这样的情况被认为是不理想的,因为它可能导致数据冗余和不一致。 如果一个关系或表满足上述条件,那么它就处于第四...

    数据库-范式及范式分解复习知识

    第三范式(Third Normal Form, 3NF)要求关系模式`R`中所有的非主属性完全函数依赖于候选键,或者与候选键成函数依赖。具体来说,一个关系模式`R`是第三范式的,当所有的`F+`中的` `至少满足以下三个条件之一:...

    数据库3-4 关系范式及模式分解1

    在数据库设计过程中,我们还会用到**Boyce-Codd范式(BCNF)**和**第4范式(4NF)**,它们分别进一步解决了依赖问题和多值依赖问题。BCNF要求任何非平凡的函数依赖X→Y,X都必须是超键,而4NF则关注多值依赖,确保非...

    数据库范式5nf-第五范式(5NF)数据库管理系统.pdf

    第五范式(5NF),又称投影联合范式(PJ/NF),是数据库规范化的一个高级阶段,它主要关注的是消除特定类型的冗余和依赖,特别是与多值依赖相关的冗余。 5NF的定义是:一个关系R处于5NF,当且仅当其每一个非平凡的...

    6-4 关系范式的概念,1NF 2NF1

    除了这些基本范式,还有BCNF(Boyce-Codd范式)和4NF(第四范式),它们分别处理了更复杂的情况,如消除对候选键的非平凡依赖和多值依赖。5NF(第五范式,又称投影连接范式)是规范化的一个更高级别,它要求所有属性...

    第3章 关系模式设计理论 3.6 多值依赖和第4范式.flv

    数据库系统原理

    05-数据库设计三范式1

    在关系数据库中,1NF 是最基本的要求,它要求数据库表的每一列都是不可分割的基本数据项,同一列中不能有多个值。如果一个属性(列)可以分解成更小的部分,那么就违反了第一范式。例如,将“地址”属性设计为一个...

    数据库范式.pdf

    消除多值依赖。 第五范式(5NF) 消除循环依赖。 此外,还有其他重要的概念,例如: 函数依赖 当 Y 的值由 X 决定的时候,我们就说 Y 函数依赖于 X。 决定因素 如上例中,CategoryID 就是一个决定因素,他决定着...

    数据库范式理解例题.doc

    以下是关于数据库范式的一些核心知识点: 1. **主属性与非主属性**: - 主属性是包含在任何候选键(能唯一标识元组的最小属性组合)中的属性。 - 非主属性则是不包含在任何候选键中的属性。 2. **函数依赖**: ...

    通俗易懂,实例讲解数据库范式,三范式,六范式

    ##### 第四范式(4NF): 消除多值依赖 - **前提条件**:符合3NF。 - **定义**:消除非平凡且非函数的多值依赖。 - **示例**:假设一个图书表中,一本书可以有多位作者,多位作者也可以共同写多本书,这需要通过第四...

    数据库范式以及范式的级别

    4NF针对多值依赖,即一个非主属性依赖于另一个非主属性的集合。如果存在多值依赖,应将其拆分为更小的表,以消除这种依赖。 五、第五范式(5NF,也称为投影-连接范式PJ/NF) 5NF是最高级别的范式,它要求消除投影-...

    数据库中的范式理论的详解

    5. **第四范式(4NF)**:旨在解决多值依赖问题,确保表中的每一个非平凡多值依赖的左部包含所有的主键属性。换句话说,就是要消除多值依赖,即将表分割成尽可能小的块。 6. **第五范式(5NF)**:也称为投影-连接范式...

    三大范式应用与理解

    这意味着数据库表中的每个单元格只能包含一个值,不能是多个值的组合。例如,一个字段不应包含多个子字段。在现代的关系数据库管理系统中,由于它们不允许列的子划分,因此大多数表天生就是1NF。 第二范式(2NF)...

    关系模式的范式

    - **第四范式(4NF)**:对于每一个非平凡的多值依赖\( X \rightarrow \rightarrow B \),都有\( X \)包含码。 - **第五范式(5NF)**:也称为投影-连接范式,确保模式满足某些特定的投影-连接属性。 #### 三、总结 ...

    数据库三范式(六范式)--通俗易懂

    - **定义**:在满足3NF的基础上,消除非平凡的多值依赖。 - **示例**:如果一个表中存在一个属性A,它可以关联多个属性B,但与码无关,则违反4NF。 ##### 第五范式(5NF) - **前提条件**:表需满足第四范式。 - *...

    数据库函数依赖关系模式范式候选键主键码学习教案.ppt

    函数依赖关系是指在关系模式中,一个或多个属性的值决定了另一个或多个属性的值。函数依赖关系是数据库设计中最基本的概念之一。例如,在一个学生数据库中,学生的学号决定了学生的姓名、年龄、班级等信息。这里,...

    13.Mysql范式1

    五级范式是在四级范式的基础上进一步规范化的结果,它要求每个表中的每一行都具有唯一的主键,并且每一列都完全函数依赖于主键,并且不存在传递函数依赖,并且不存在部分函数依赖,并且不存在多值依赖,并且不存在...

Global site tag (gtag.js) - Google Analytics