第四部分 - 方法学 - 1 - 概念数据库设计

回顾数据库设计三个阶段:
概念数据库设计:生成数据库的概念表示,包括重要的实体、联系以及属性的定义。
逻辑数据库设计:将概念表示转换成数据库额的逻辑结构,包括关系的设计。
物理数据库设计:如何在目标数据库管理系统(DBMS)中物理的实现逻辑结构(作为基础关系)。

1. 数据库设计方法学简介

1.1 什么是设计方法学

设计方法学:一种结构化的方法,它用过程、技术、工具以及文档等辅助手段来支持和简化设计过程。

设计方法学的每个阶段都是由若干步骤组成的,这些步骤指导设计者在工程的各个阶段采用相应的合适的技术。设计方法学同样帮助设计者对数据库系统开发项目进行计划、管理、控制和评估。并且,设计方法学是结构化的方法,因为设计方法学用标准化和组织化的方式对数据库系统的一系列需求进行分析和建模。

1.2 概念、逻辑和物理数据库设计

在数据库设计方法学中,设计过程被分为三个主要阶段:概念数据库设计,逻辑数据库设计,物理数据库设计。

概念数据库设计:在不考虑任何物理因素的情况下构建企事业单位数据模型的过程。

概念数据库设计从创建企事业单位的概念数据模型开始,概念数据模型完全独立于诸如 DBMS、应用程序、编程语言、硬件平台、性能问题或其他物理因素等实现细节。

逻辑数据库设计:在不考虑具体 DBMS 和其他物理因素的情况下基于特定的数据模型构建企事业单位的数据模型的过程。

逻辑数据库设计阶段将概念模型映射为逻辑模型,该逻辑模型受到目标数据库数据模型(如关系模型)的影响。逻辑数据模型是物理设计阶段的基础,为物理数据库的设计者进行全面考虑和权衡提供依据,这对涉及高校的数据库十分重要。

物理数据库设计:在二级存储器上实现数据库的过程,包括定义基础关系、文件组织、用于实现高效数据访问的索引,以及相关的完整性约束和安全机制。

在物理数据库设计阶段,设计者可以自行决定实现数据库的方式。物理设计因 DBMS 而异。在物理设计和逻辑设计之剑存在着反馈过程,因为在物理设计过程中为提高性能所采取的措施可能会影响逻辑数据模型。

1.3 成功设计数据库的关键因素

通常,下面几点对数据库设计的成功与否至关重要:

  • 尽可能多的和用户交流。
  • 在数据建模的整个过程中遵循结构化的方法学。
  • 使用数据驱动方法。
  • 在数据模型中综合考虑结构性和完整性。
  • 数据建模方法学应该结合概念化、规范化和事务验证技术。
  • 尽可能多的用图表来描述数据模型。
  • 用数据库设计语言(Database Design Language,DBDL)来描述难以用图表表达的数据的语义。
  • 建立数据字典对数据模型图和 DBDL 进行补充说明。
  • 自觉地迭代。

2. 数据库设计方法学概述

数据库设计方法学包括以下步骤。

概念数据库设计

  • 步骤 1 建立概念数据模型
    • 步骤 1.1 标识实体类型
    • 步骤 1.2 标识联系类型
    • 步骤 1.3 表示属性并将属性与实体或联系类型相关联
    • 步骤 1.4 确定属性域
    • 步骤 1.5 确定候选关键字、主关键字和可替换关键字属性
    • 步骤 1.6 考虑使用增强的建模概念(可选步骤)
    • 步骤 1.7 检查模型的冗余
    • 步骤 1.8 针对用户事务验证概念模型
    • 步骤 1.9 与用户一起复查概念数据模型

关系模型的逻辑数据库设计

  • 步骤 2 建立逻辑数据模型
    • 步骤 2.1 从逻辑数据模型中导出关系
    • 步骤 2.2 使用桂芳化方法验证关系
    • 步骤 2.3 针对用户事务验证关系
    • 步骤 2.4 检查完整性约束
    • 步骤 2.5 与用户一起复查逻辑数据模型
    • 步骤 2.6 将逻辑数据模型合并为全局模型(可选步骤)
    • 步骤 2.7 检查模型对未来可拓展性的支持

关系数据库的物理数据库设计

  • 步骤 3 转换逻辑数据模型以适应目标 DBMS

    • 步骤 3.1 设计基础关系
    • 步骤 3.2 设计导出数据的表示方法
    • 步骤 3.3 设计一般性约束
  • 步骤 4 设计文件组织方法和索引

    • 步骤 4.1 分析事务
    • 步骤 4.2 选择文件组织方法
    • 步骤 4.3 选择索引
    • 步骤 4.4 估计所需的磁盘空间
  • 步骤 5 设计用户视图

  • 步骤 6 设计安全机制

  • 步骤 7 考虑引入可控冗余

  • 步骤 8 监控系统和系统调优

从相对简单的数据库系统到高度复杂的数据库系统,都可以使用上述方法学进行数据库系统的设计。在数据库系统开发的生命周期中,数据库设计被分为三个阶段,分别是概念设计、逻辑设计和物理设计。因此,方法学也包括三个相应的阶段:步骤 1 是概念数据库设计,步骤 2 是逻辑数据库设计,步骤 3 ~ 8 是物理数据库设计。根据要建立的数据库系统复杂程度不同,有些步骤可以省略。例如,对于不管是单用户视图的数据库系统,还是用集中式方法处理多用户视图的数据库系统,方法学中的步骤 2.6 都显然是多余的。因为我们只需要在步骤 1 中创建一个单一的概念数据模型,或者在步骤 2 中创建一个单一的逻辑数据模型就可以了。如果数据库设计人员在设计数据库系统时使用了视图集成的方法处理多个用户视图,就需要反复应用步骤 1 和步骤 2,直到完成了所有模型的创建,然后再步骤 2.6 再将这些模型合并。

前面我们使用的术语 “局部概念数据模型” 和 “局部逻辑数据模型” 是指对数据库系统的一个或者多个(不是全部)用户视图建模,术语 “全局逻辑数据模型” 则指对数据库系统的所有用户视图建模。在方法学中,除了可选步骤 2.6 外,适用的都是一般性的术语 “概念数据模型” 和 “逻辑数据模型”,在步骤 2.6 中因为要描述的任务是将各个局部逻辑数据模型合并为全局逻辑数据模型,所以使用了术语。

设计方法学中一个很重要的方面是:不断地对生成的模型进行验证,以保证其始终能够准确地反映被建模的那部分企事业单位的需求。在数据库设计方法学,可以使用多种方法对数据模型进行验证,例如规范化、确保对关键事务的支持、要求尽可能多的与用户一起验证数据模型。

步骤 2 所建立的逻辑模型是步骤 3 到步骤 8 进行物理数据库设计的基础。同样,根据数据库系统的复杂性以及目标 DBMS 的功能,物理数据库设计的某些步骤也可以省略。例如,对于基于 PC 的 DBMS,步骤 4.2 就可以省略。

数据库设计是一个反复迭代的过程,其不断求精的过程几乎没有止境。尽管方法学的步骤是一个程序式的过程,但必须强调的是这并不意味着时记得设计过程就是按照这些步骤进行的。从某一个步骤里获得的信息有可能改变前一个步骤的结果,同样的,前一个步骤的修改有可能影响后面的步骤。所以,方法学就是一个框架,他引导设计者有效的进行数据库设计。

我们使用 DreamHome 案例研究来说明数据库的设计方法。DreamHome 数据库包含多个用户视图(Director、Manager、Supervisor、Assistant 和 Client),并使用视图集成和集中的方法来处理它们。应用集中的方法生成了两类视图:StaffClient 用户视图和 Branch 用户视图。这两类视图分别包括:

  • StaffClient 用户视图 —— 包括了主管(Supervisor)、助理(Assistant)和客户(Client)的用户视图。
  • Branch 用户视图 —— 包含负责人(Director)和经理(Manager)的用户视图。

3. 概念数据库设计方法学

步骤 1 建立概念数据模型

目标——创建一个满足企事业单位数据需求的概念数据模型。

概念数据库设计的第一步是建立一个(或多个)满足企事业单位数据需求的概念数据模型。一个概念数据模型包括:

  • 实体类型
  • 联系类型
  • 属性和属性域
  • 主关键字和可替换关键字
  • 完整性约束

概念数据模型由 ER 图、数据字典等文档支持,这些文档是在模型开发过程中逐步生成的。在后面的每个步骤中我们都将说明该步骤生成的支持文档的类型。步骤 1 的任务是:

  • 步骤 1.1 标识实体类型
  • 步骤 1.2 标识联系类型
  • 步骤 1.3 表示属性并将属性与实体或联系类型相关联
  • 步骤 1.4 确定属性域
  • 步骤 1.5 确定候选关键字、主关键字和可替换关键字属性
  • 步骤 1.6 考虑使用增强的建模概念(可选步骤)
  • 步骤 1.7 检查模型的冗余
  • 步骤 1.8 针对用户事务验证概念模型
  • 步骤 1.9 与用户一起复查概念数据模型
步骤 1.1 标识实体类型

目标——标识所需的实体类型

创建概念数据模型的第一步是定义用户关心的主要对象。这些对象就是模型的实体类型。确定实体的一种方法是审查用户需求规格说明书。我们可以标出需求规格说明书中的名词和名词短语(如员工编号、员工姓名、房产所有者编号、房产所有者地址、租金、房间数等)。当然,我们要找出主要的对象,如人、地址或者是感兴趣的概念,排除那些仅仅用来描述对象性质的名词。比如,我们可以将员工编号和员工姓名组成一个名为 Staff 的对象或者实体,将房产编号、房产地址、租金和房间数组成一个名为 PropertyForRent 的实体。

确定实体的另外一种方法就是查找那些客观存在的对象。比如说 Staff 是一个实体,因为不管我们知不知道他们的名字、职务以及出生日期,员工都会客观存在。可能的话,用户应该协助完成这个任务。

由于用户的需求规格说明书的表达方式各不相同,所以确定实体有时会比较困难。用户经常采用例子和类比。比如用户通常直接提到某人的名字,,而不用我们所需要的一般意义上的 “员工” 这个名词。有时,用户使用工作角色之类的名词,特别是经常使用某个人所属的单位名称。这些角色可能是工作头衔或职务,如负责人、经理、主管或助理等。

用户经常混用同义词或歧义词,从而使事情变得更加复杂。意义相同的两个词叫同义词,例如,“branch” 和 “office”。歧义词是指在不同的上下文中有不同含义的词。例如,单词 “program” 有几种不同的意思,如一种学习的课程、一系列事件、一个工作计划或一段电视节目。

某个对象是否就是实体、联系或者属性并不显而易见。例如,婚姻应该归为哪一类?事实上,根据实际需求,它既可以属于三者众的任一类型也可同时属于三种类型。设计是主观的,不同的设计者可能有不同的设计,但是这些设计都应该同等有效,并且在解释上也应该是等同的。因此在某种程度上,这个过程依赖于设计者的判断力和经验。数据库设计者必须对现实世界做出一定的取舍,并对所观察的企事业单位内部的情况进行分类。因此,根据所给的需求规格说明书,不一定总会推导出唯一的实体类型集。但设计过程的不断迭代至少会选出满足系统需求的实体。对于 DreamHome 的 StaffClient 用户视图,我们标识出如下实体:

  • Staff
  • PropertyForRent
  • PrivateOwner
  • BusinessOwner
  • Client
  • Preference
  • Lease

用文档记录实体类型

标识出实体类型后,应为其指定有意义并且很容易被用户理解的名字,并且将这些尸体的名字及描述记录在数据字典中。如果可能,记录每个实体期望出现的次数。如果一个实体有多个名字,则把他们定义为 同义词别名,并记录到数据字典中去。下图显示了数据字典的一部分,记录了 DreamHome 中 StaffClient 用户视图的实体。

节选数据字典关于 DreamHome 的 StaffClient 用户视图中实体的描述
步骤 1.2 标识联系类型

目标——标识实体类型之间的重要联系

标识实体后,下一步就是表示所有存在与这些实体间的联系。标识实体的一种办法就是找出用户需求规格说明书中出现的名词。同样,我们可以用需求规格说明书中的文法来识别联系。通常,联系体现在动词或动词词组上面。例如:

  • Staff Manages PropertyForRent(员工管理房产)
  • PrivateOwnerr Owns PropertyForRent(业主拥有房产)
  • PropertyForRent AssociatedWith Lease (房产关联着租约)

需求规格说明书之所以记录这些联系,是因为它们对企事业单位很重要,因此在模型中应该包含他们。我们只对实体之间需要的联系感兴趣。

上例中,我们标识出了 Staff Manages PropertyForRent 和 PrivateOwner Owns PropertyForRent 两种联系。当然,也可以考虑 Staff 和 PrivateOwner 之间的联系(例如 Staff Assists PrivateOwner(员工帮助业主))。尽管它是一种可能的联系,但从需求规格说明书来看,建模时并不需要它。

大多数情况下,联系是二元的,即联系仅存在于两个实体类型之间。但我们也要注意多个实体类型之间的复杂联系以及单个实体类型的递归联系。

设计者必须仔细分析,确保识别出用户需求规格说明书中显式或隐式说明的所有联系。原则上说,应该检查每一对实体类型,找出所有潜在的联系。但是,这对于一个包含了几百个实体类型的大系统来说过于复杂。另一方面,不做这样的检查又不太明智,这通常是分析员和设计院的责任。不过,当我们针对要支持的事务验证模型时也应该很容易发现那些遗漏的联系。

使用实体-联系(ER)图

用可视化的方式描述复杂系统通常要比使用冗长的文本描述容易得多。使用 ER 图来描述实体和它们之间的联系要更简单一些。在数据库设计的整个阶段,强烈建议在需要的时候尽量使用 ER 图来标识企事业单位建模的各个部分。本书使用最新的面向对象表示方法——统一建模语言(UML),不过其他表示方法也可以完成类似的功能。

确定联系类型的多重性约束
联系确定以后,下一步就是要确定每一种联系的多重性。如果已经知道联系的多重性的取值,或者知道取值的上限和下限,那么直接记录下来就可以了。

多重性约束主要用于检查和维护数据。更新数据库时,可以根据多重性约束判断此次更新是否违反了企事业单位声明的规定,因此多重性约束是实体的实例出现能否被录入的准则。具有多重性约束的模型能够更加明确的表述联系的语义,从而更好地表示企事业单位的数据需求。

检查扇形陷阱和断层陷阱

必要的联系确定以后,还要检查 ER 模型中的每个联系是否准确的描述了 “现实世界”,确保没有无意中形成的扇形陷阱和断层陷阱。
下图为 DreamHome 案例中用户视图 StaffClient 的ER 图的初步构想。

DreamHome 中用户视图 StaffClient 的实体和联系类型的 ER 图

用文档记录联系类型

确定好联系类型以后,还要赋予他们有意义并且容易被用户理解的名字。同时还要在数据字典中记录联系的描述以及多重性约束。下表显示了数据字典中关于 DreamHome 的用户视图 StaffClient 的部分内容。

节选数据字典中关于 DreamHome 的用户视图 StaffClient 的联系的描述
步骤 1.3 标识属性并将属性与实体或联系类型相关联

目标——将属性与相应的实体和联系类型关联在一起。

方法学的下一个步骤就是要确定那些已经被选定要在数据库中表示的实体和联系的属性。类似于实体的确定,我们继续在用户需求规格说明书中寻找名词和名词短语。若名词或名词短语是实体或联系的一种特性、性质、标识符或特征时,即可标识为属性。

当我们已经在需求规格说明书中标识出了实体(x)或联系(y)以后,接下来就可以问自己 “对于 x 或 y,我们需要保留它们的哪些信息?” 到现在为止这是确定属性最简单的方法,而问题的答案应该在需求规格说明书中有清楚的描述。但是在某些情况下,可能还有必要请用户对需求进行澄清。遗憾的是,用户对这些问题的回答又可能会涉及一些其他的概念,因此对用户的回答必须仔细斟酌。

简单 / 组合属性

判别属性是简单属性还是组合属性十分重要。组合属性由简单属性构成。例如,address 属性可以是简单属性,它将所有的地址细节作为一个单值,如 “115 Dumbarton Road,Glasgow, G11 6YG”。然而,该地址也可被视为一个组合属性,它由若干简单属性组成,比如 street(“115 Dumbarton Road”)、city(“Glasgow”)和 postcode(“G11 6YG”)。选择用简单属性还是组合属性描述地址,取决于用户需求。如果用户不需要单独访问地址中的某个组成部分,就可以将 address 作为一个简单属性处理,反之,address 就要作为组合属性,由所需的简单属性构成。

在这个步骤中,重要的是我们要表示出概念数据建模中的所有简单属性,包括那些组成组合属性的属性。

单值 / 多值属性

属性除了有简单和合成之分外,还有单值或多值的分别。大多数属性都是单值的,但也会有一些多值属性,即一个实体的某个属性可能有多个值。例如,实体 Client 的 telNo(电话号码)属性就可以是多值属性。

另一方面,客户的电话号码也可被视为独立于客户的另一实体。在设计模型时,这两种方案都是可行的,而且同样有效。在步骤 2.1 中我们会看到,多值属性被映射为关系,所以两种方法产生的结果是一样的。

导出属性

其值依赖与其他属性值得属性称为导出属性。导出属性的例子包括:

  • 员工的年龄
  • 一个员工管理的房产数量
  • 押租(一般按两倍月租计算)

一般情况下,导出属性不在概念数据模型中描述。但有时候导出属性依赖的属性和属性值会被删除或修改,此时导出属性就必须在概念数据模型中描述,以避免可能的信息丢失。如果一个导出属性出现在模型中,就必须注明它是导出的。导出属性的表示形式将在物理数据库设计时考虑。根据导出属性使用方式的不同,导出属性的值可在每次被访问时计算,或者在其所依赖的属性值发生变化时计算。不过,概念数据库设计并不关心这个问题,这部分内容将在讨论步骤 3.2 是讲述。

潜在问题

在为视图标识实体、联系和属性时,常常会从最初是的选择中遗漏一个或多个实体、联系或者属性。这种情况下,我们需要返回到前面的步骤,记录新确定的实体、联系或属性,并重新检查所有相关的联系。

通常属性的数量要比实体和联系多,最好先对用户需求规格说明书中给出的所有属性做个列表。一旦发现某个属性和某个实体或联系相关联,就从列表中删除该属性。这样能确保一个属性只与一个实体或联系类型关联。当列表为空时,所有属性就都和实体或联系类型关联起来了。

要当心可能存在一个属性与多个实体或联系类型相关联的情况,原因可能是:

  1. 我们已经确定了多个实体,其实这些实体可以被抽象为一个实体。例如,我们可能已经确定了实体 Assistant 和 Supervisor,它们都包含属性 staffNo、name、sex 和 DOB,其实这两个实体都可以用实体 Staff 来表示,而 Staff 的属性包括 staffNo、name、sex、DOB 和 position(其值是助理或主管)。另一方面,这些尸体也可能共同拥有某些属性,然后有各自拥有一些特殊属性。这时,我们必须决定是将这些实体泛化为一个单一的实体(如 Staff),还是将它们作为分别表示不同职业角色的特殊化实体来对待。关于特殊化还是泛化实体的问题已经在增强实体-联系建模部分讨论过,在步骤 1.6 中还会有更详细的说明。

  2. 我们在实体类型间已确定了一个联系。此时,属性只能与唯一一个实体,就是父实体关联,并确保该联系已在前面的步骤 1.2 中被标识。如果不是这样,就应该更新文档,将新确定的联系写入文档。例如,假设我们已经确定了实体 Staff 和 PropertyForRent 及其属性:

Staff                     staffNo, name, position, sex, DOB
PropertyForRent           propertyNo, street, city, postcode, type, rooms, rent, managerName

PropertyForRent 中,属性 managerName 表示联系 Staff Manages PropertyForRent。此时,应该将属性 managerName 从 PropertyForRent 中删除掉,并增加联系 Manages。

DreamHome 中实体的属性

对于 DreamHome 的用户视图 StaffClient,我们可以确定以下实体及其属性:

Staff             staffNo, name(fName, lName), position, sex, DOB
PropertyForRent   propertyNo, address(street, city, postcode), type, rooms, rent
PrivateOwner      ownerNo, name(fName, lName), address, telNo
BusinessOwner     ownerNo, bName, bType, address, telNo, contactName
Client            clientNo, name(fName, lName), telNo, eMail
Preference        prefType, maxRent
Lease             leaseNo, paymentMethod, deposit(deposit = PropertyForRent.rent * 2), depositPaid, rentStart, rentFinish, duration(duration = rentFinish - rentStart)

DreamHome 中联系的属性

一些属性不应该和实体关联,而应该和联系相关联。对于 DreamHome 的用户视图 StaffClient,属性与联系关联的情况如下:

Views   viewDate, comment

用文档记录属性

确定了属性以后,还要为他们指派对用户而言有意义的名字。每个属性需要被记录的信息包括:

  • 属性名和说明。
  • 数据类型和长度。
  • 该属性已知的所有别名。
  • 属性是否为组合的,如果是则给出组成它的简单属性。
  • 该属性是否为多值得。
  • 该属性是否为导出的,如果是应该如何计算它。
  • 该属性的默认值。

下图给出了数据字典中记录 DreamHome 中用户视图 StaffClient 的属性的部分内容。

节选数据字典中关于 DreamHome 中用户视图 StaffClient 的属性的描述
步骤 1.4 确定属性域

目标——确定概念数据模型中属性的域

步骤 1.4 的目的视为模型中的所有属性确定域。域是值集,一个或多个属性可以从中取值。例如,可以定义:

  • 合法员工编号(staffNo)的属性域是五个字符长的字符串,头两个是字母,接着三个是数字,数字范围是 1 ~ 999。
  • 实体 Staff 的属性 sex 的可能值要么是 “M”, 要么是 “F”。这个属性的域是单字符的字符串,由 “M” 或 “F” 构成。

完善的数据模型应为每个属性指定域,包括:

  • 属性的合法值的集合。
  • 属性的存储空间大小和格式。

还有更多的信息可用于说明域,如属性上允许的操作,哪些属性可以相互比较,或者那些属性可以相互结合。不过,如何在 DBMS 中实现属性域的这些特性仍然处于研究阶段。

文档记录属性域

确定属性域后,在数据字典中记录属性域的名字和特性。更新数据字典,用属性域替代属性的数据类型和长度信息。

步骤 1.5 确定候选关键字、主关键字和可替换关键字属性

目标——为每个实体类型确定候选关键字,如果有多个候选关键字,则选择一个作为主关键字,其他作为可替换关键字。

这个步骤主要考虑为实体确定候选关键字,并选择其中一个作为主关键字。候选关键字 是实体中可以唯一确定该实体每个出现的最小属性集合。我们可以确定出多个候选关键字,然而必须从中选择一个作为 主关键字,剩下的候选关键字称为 可替换关键字

人名通常做不了候选关键字。例如,读者可能认为组合属性 name 即员工的姓名适合作为实体 Staff 的候选关键字。然而,DreamHome 中有可能两个人同名,很显然,name 作为候选关键字是不合适的。同样,DreamHome 中的业主的名字也有类似的问题。这种情况下,尽管我们可以考虑将若干属性组合在一起以满足唯一性,但更好的方法是使用一个已经存在并能保证唯一性的属性,如实体 Staff 的属性 staffNo 和实体 PrivateOwner 的属性 ownerNo,或者定义一个新的能保证唯一性的属性。

从候选关键字中选择主关键字时,可以参考以下原则:

  • 包含属性个数最少的候选关键字。
  • 属性值被修改的可能性最小的候选关键字。
  • 字符数最少的候选关键字(对于文本属性)。
  • 最大值最小的候选关键字(对于数值属性)。
  • 从用户的角度看最容易使用的关键字。

在确定主关键字的过程中,要注意实体的强弱。如果能为一个实体指定关键字,该实体就是 强实体,否则就是 弱实体。可以通过设置外部关键字,将弱实体和其所有者实体关联起来,然后确定弱实体的主关键字。步骤 2.1 描述了将实体和实体间的联系映射为关系的过程,到这一步才能为弱实体指定主关键字。

DreamHome 的主关键字

下图给出了 DreamHome 的 StaffClient 用户视图的主关键字。注意 Preference 实体是个弱实体,联系 Views 由两个属性:viewDate 和 comment。

增加了主关键字的 DreamHome de StaffClient 用户视图的 ER 图

用文档记录主关键字和可替换关键字

在数据字典中记录主关键字和所有可替换关键字标识。

步骤 1.6 考虑使用增强的建模概念(可选步骤)

目标——考虑使用增强的建模概念,如特殊化 / 泛化、聚合和组合。

在这个步骤中,可选择使用增强实体-联系建模中讨论的特殊化 / 泛化、聚合和组合等高级建模概念,继续改进 ER 模型。如果使用特殊化方法,就要定义一个或多个 子类超类 实体来体现实体间的不同。如果使用泛化方法,就要寻找实体间的共同特征,以定义一个泛化的超类实体。可以使用聚合表示实体间的 “拥有” 或 “属于” 联系,其中一个实体是 “整体”,另一个则是 “部分”。可以使用组合(一个特殊的聚合)表示在 “整体” 和 “部分” 之间具有强附属关系以及相同的生命周期。

对于 DreamHome 的 StaffClient 用户视图,对 PrivateOwner 和 BusinessOwner 这两个实体进行泛化,创建一个包含公共属性 ownerNo、address 和 telNo 的超类 Owner。超类 Owner 和它的子类之间是强制参与和不相交的联系,记为 {Mandatory,Or}:超类 Owner 的每一个成员必须是其中一个子类的成员,但不能同时属于两个。

此外,我们创建 Staff 的一个特殊化子类 Supervisor,并特别构建联系 Supervises。超类 Staff 和子类 Supervisor 的联系是可选参与的,超类 Staff的成员不必是子类 Supervisor 的成员,为了使设计简单,我们不使用聚合和组合。修改后的 DreamHome 的 StaffClient 用户视图的 ER 图如下所示。

特殊化 %2F 泛化后的 DreamHome 的 StaffClient 用户视图的 ER 图

在选用高级建模概念开发 ER 模型时没有严格的规定,基本上取决于设计者的主观意志以及所建模型的特征。从经验上来说,选择使用这些概念时,要能使 ER 图尽可能清楚的表示重要的实体以及它们之间的联系。因此,应根据 ER 图的可读性,以及描述重要实体和联系时的清晰程度决定高级建模概念的选用。

虽然这些概念是和增强的 ER 模型相关的,但因这一步是可选的,所以在整个方法学中仍然简单地用 “ER 图” 代表数据模型的图形表示。

步骤 1.7 检查模型的冗余

目标——检查模型中任何存在的冗余

步骤 1.7 检查概念数据模型中是否存在任何冗余,若有,则删除它们。这一部主要的活动有:

  • 重新检查一对一(1:1)联系。
  • 删除冗余的联系。
  • 考虑时间因素。
1. 重新检查一对一(1:1)联系

在确定实体的过程中,可能发现两个实体表示企事业单位中的同一个对象。例如,可能确定两个实际上相同的实体 Client 和 Renter,换句话说,Client 和 Renter 是同义词。这种情况下,两个实体应该合为一个。如果主关键字不同,选择一个作为主关键字,将另外一个作为可替换关键字。

2. 删除冗余的联系

如果一个联系表示的信息能够通过其他联系获得,这个联系就是冗余的。我们要努力创建最小的数据模型,所以冗余的联系是不必要的,应该删除。注意,虽然确定两个实体间是否存在多个路径比较容易,但这不意味着某个联系就是多余的,他们完全可能表示两个实体间不同的关联。例如,考虑下图中的实体 PropertyForRent、Lease 和 Client 之间的联系。

删除冗余联系 Rents

在实体 PropertyForRent 和 Client 之间有一条间接路径,即通过中间实体 Lease 的联系 Holds 和 AssociatedWith。在判断这两条路径是否都需要之前,我们要先弄清楚创建者两条路径的目的。联系 Rents 表示某个客户租用某处房产。另一方面,联系 Holds 表示某个客户是一个租用关系的实施者,联系 AssociatedWith 则表示该租用关系的租用对象是某处房产。现实生活中,尽管在客户和他们租用的房产之间确实存在联系,但一般不是直接联系,这种联系通过租用关系关联显得更加准确。因此,联系 Rents 是一个冗余联系,因为它并没有表示出实体 PropertyForRent 和 Client 之间更多的、用通过实体 Lease 的间接关联无法正确表示的信息。为了创建最小化的模型,冗余联系 Rents 必须删除。

3. 考虑时间因素

在考虑冗余时,联系的时间因素很重要。例如,考虑这样的情形——在实体 Man、 Woman 和 Child 之间建立联系,如下图所示。

非冗余联系 FatherOf 的例子

很明显,在 Man 和 Child 之间有两个路径:一个是通过直接联系 FatherOf,另一个则是通过联系 MarriedTo 和 MotherOf。进而,我们会认为联系 FatherOf 是不必要的,然而这并不正确,原因是:

  • 父亲可能会因为先前的婚姻而有孩子,而该模型中只用一个一对一联系表述父亲当前的婚姻情况。
  • 父亲和母亲可能没有结婚,或者父亲与不是孩子母亲的人jiehun(或者母亲与不是孩子父亲的人结婚)。

无论哪种情况,没有 FatherOf 联系的话,所需要的联系就不能构建出来。这个例子说明在考虑冗余时,检查实体间的每个联系含义都很重要。最后,我们通过删除任何内在的冗余简化了局部概念数据模型。

步骤 1.8 针对用户事务验证概念模型

目标——确保概念模型支持所需要的事务。

至此我们已经有了一个表示企事业单位数据需求的概念数据模型。本步骤的目的是检查模型以确保模型支持所需要的事务。在这个模型的基础上,我们尝试以手工的方式模拟运行企事业单位的业务。如果能用这种方法完成所有事物,我们就能验证这个概念数据模型是支持这些食物的。然而,如果某个事物不能手工完成,则数据模型可肯定存在必须解决的问题。出现这种情况的原因可能是数据模型中遗漏了某个实体、联系或属性。

可以通过两个步骤验证概念数据模型是否支持所需要的事务:

  • 描述事务。
  • 使用事务路径。

描述事务

在这个步骤中,用文档写出模型中每个事务的需求,我们就可以检验该模型是否支持每个事务所需要的所有信息(实体、联系和属性)。

使用事务路径

第二步是针对所需的事务验证概念模型,验证方法是在 ER 图中直接标出每个事务所有的路径。

步骤 1.9 与用户一起复查概念数据模型

目标——和用户一起复查概念数据模型以确保该模型真实地描述了企事业单位的数据需求。

在步骤 1 完成之前,我们和用户一起复查概念数据模型。概念数据模型包括 ER 图和描述数据模型的支持文档。如果数据模型中存在任何问题,我们必须进行适当的修改,这可能需要重复前面的步骤。这个过程可能需要重复多次,直到用户确认该模型确实 “真实地” 表现了被建模的那部分企事业单位需求。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容