第6章 SQL Server数据库设计

6.1. 概述
数据库设计是指对于给定的一个应用环境,构造最优的数据库模式,使之能够有效地存储数据,满足各种用户的应用需求(信息要求和处理要求)。
可以将数据库设计理解成三个要素:应用环境、数据库模式(数据模型)和满足的功能。应用环境指的是应用需求,即包括需要满足在特定条件下特定的业务需求,不能单纯理解为计算机的软件和硬件环境。首先应当重视的是应用需求,有许多数据库设计者收集应用需求及进行需求分析是业务人员的事情,只是一味地等着业务人员提供一份完整的应用需求而不会主动地参与其中,这也是为什么有人在数据建模时无所适从的主要原因(当然,这并不包括那些在进行系统开发时从不进行数据建模的人)。第二个需要注意的是不能将数据库设计与应用程序设计分隔开来,数据库设计并不是为了完成一个所谓的最优数据库模式,而是为了“满足各种用户的应用需求”。如果你重视了数据库设计的前因后果,那么数据库设计的工作就会变得容易些,至少不至于无所适从。但数据库设计与其它工程设计一样,都需要掌握相应的设计方法和丰富的经验才能设计出好的模型。
数据库设计包含的艺术成份多于科学成份,也可以说它是一门艺术而不是一门科学。尽管在数据库设计领域中有一些理论或方法可以应用,但仅靠这些理论或方法并不能很好地完成数据库设计,它需要大量的经验和创造性。这就象计算机程序设计一样,仅靠程序设计的理论或方法是不可能完成高质量程序的设计。因此,在数据库设计这个问题上,许多人会在学习完设计方法后对具体的应用问题时仍然是无所适从,不知道从哪里下手,该如何进行,特别是该如何设计一个好的数据库系统。
本章所讲述的内容是让你了解有哪些数据库设计方法,其中详细介绍了IDEF1X数据建模方法,你可以在学习完本章后进行一些简单的数据库系统的设计。
数据库设计不仅仅是得到一个正确的数据结构,数据完整性是数据库数据库设计的关键要素之一。
6.1.1. 数据库设计方法
尽管在数据库设计中方法并不起决定性的作用(主要靠设计者的经验和创造性),但方法是设计一个优秀数据库系统的基础。因此,要想设计好数据库,必须先掌握一定的数据库设计方法。
有许多数据库设计方法,如Barker设计方法、新奥尔良(New Orleans)方法等。这些方法的核心阶段是数据建模,而数据建模又包括逻辑建模和物理建模阶段。
逻辑建模阶段完成数据库的逻辑模型设计。逻辑模型是只考虑业务需求而不考虑具体的DBMS环境的一种数据模型,虽然有许多逻辑模型是为构建一个数据库系统而设计的,但有些逻辑模型可能是用于其它的目的,如业务流程重组中的业务流程分析。逻辑建模阶段是数据库设计最重要的一个阶段。
物理建模阶段完成数据库的物理模型的设计。物理模型是针对特定DBMS而设计的数据模型,它往往是将逻辑模型映射到特定DBMS,也就是在逻辑模型的基础上设计完成的。由于物理模型涉及到特定DBMS,因此,目前关于物理模型的设计还没有一个通用的方法以指导物理模型的设计。
Barker方法是以Oracle公司的董事Richard Barker先生命名的。Barker先生负责设计Oracle的自动化设计工具Oracle Designer最初的工作。如图 6 1所示,Barker方法将数据库设计划分为7个设计阶段:制定策略、分析、设计、构建、编写文档、转换和产品。其中,制定策略阶段完成需求分析和基本的逻辑模型设计。在分析阶段,开发小组与关键人员进行交流,收集所有的业务需求,也就是需求分析阶段。在设计阶段,物理模型的设计是在分析阶段所确定的逻辑模型的阶段的基础上进行的。设计工作完成后,就应该构建数据库。Barker先生认为文档编写应该有一个单独的阶段来完成,它应当是在完成数据库的基本设计之后进行。在转换阶段,将准备好的数据转换到产品环境中,有许多情况下需要将数据从旧的数据库移植到新的数据库中。使用真实的数据进行测试也是这个阶段必须要完成的工作内容之一。最后一个阶段,数据库必须在产品环境下运行,它可供最终用户通过应用软件或其它的工具来访问数据库、提出修改请求、测试、再运行。
图 6 1 Barker数据库设计方法的过程
Oracle Designer采用了在Barker方法的基础修改而来的改进的设计方法,这种方法将数据库设计分成9个阶段:制定策略、预分析、分析、预设计、设计、构建、测试、实现和维护。该方法认为分析和设计阶段是两个最重要的阶段,因此,它设置了预分析和预设计阶段,分别为这两个阶段做一些准备工作,同时,它又认为测试也是一个不可忽视的工作,将其独立列为一个阶段很有必要。而实现与维护阶段相当于Barker方法的转换和产品阶段,只不过名称不同而已。
这里需要说明的是,数据库的实现与维护本身并不属于数据库设计的工作,但这两个阶段中仍有数据库设计需要完成的工作,除非你设计的系统没有一点问题。实际上,数据库设计工作覆盖了数据库系统的整个生命周期,从设置项目开始直到系统消亡(不再使用),都会有数据库设计的工作。
关系数据库设计是在数据库的物理设计阶段将数据库的逻辑设计映射到特定的关系数据库而不是其它的数据库。常见的数据库设计都是关系数据库设计,这是因为目前主流的DBMS都是关系数据库的原因。但大多数的数据库设计方法如Barker方法并不局限于关系数据库设计,你完全可以将这些方法应用于非关系数据库设计。
6.1.2. 数据模型与数据建模
模型是现实世界中某个事务或对象的模拟或抽象。
模型的特性体现在三个方面:能够比较真实地描述现实世界;简单,易于理解;便于实现。所有的模型都必须满足能够比较真实的描述现实世界这一特点,因为模型与现实世界相差太远,则模型就不能算是一个正确的模型,其它的特性就不用再考虑了。简单性决定了模型是否可以在不同的设计者之间或其它相关人员之间进行交流,一个简单、直观的模型便于交流,能够保证设计的效率与质量。模型的可实现性也很重要,设计模型的目的就是为了实现某个产品、系统等,难以实现的模型违背了模型设计的初衷。
数据模型也是一种模型,它是现实世界数据特征的抽象。
根据不同的划分,数据模型的类型不同。例如,根据数据模型所处的阶段有逻辑模型和物理模型,而物理模型又根据数据模型不同的性质可分为层次数据模型、网状模型、关系模型、面向对象模型和对象关系模型等。
DBMS对数据在数据库中的含义的理解是非常有限的:它们通常可以理解某些简单的数据值,以及这些值的某些简单约束。例如,DBMS知道存储某个学生的体重的值的具体大小及范围,它还知道存储该学生所选的某一门课程的考试成绩,但DBMS不能理解这两个值各自所包含的含义以及它们具有完全不同的含义,如果你操作DBMS去比较这两个值,它不会认为有什么不妥的地方。
显然,系统理解得越多越好,它就会越智能。例如,如果DBMS能够理解上面两个值的含义,从而知道这两个值比较是没有什么意义的,这样智能的DBMS正是我们所期望的,可惜的是,我们一时还无法看到这样的DBMS。
从数据库设计的过程可以看出,数据库设计包括了逻辑建模与物理建模,而物理模型是最终存储在特定的DBMS的数据库中。那么是否可以理解为逻辑模型只是为了完成物理模型的设计而本身没有实际的意义呢?当然不是这样。这是因为无论是数据库设计的物理模型还是逻辑模型都包含了存储在特定DBMS数据库中的数据模型所不具备的特性,即应用语义。通过数据库设计的数据模型,你可以更好地理解应用,因此,有时我们把数据库设计的数据模型称为语义模型,把数据库设计的数据建模称为语义建模,而存储在DBMS数据库中的模型则可以称为数据库模型。
自从20世纪70年代末期以来,语义建模就成为一个研究的课题。这项研究的动力—即研究者试图解决的问题是,典型的数据库系统对数据在数据库中的含义的理解是非常有限的。
语义数据模型的命名是为了与DBMS中的数据库模型进行区别,语义建模也是为了与DBMS建模进行区别。但大多数人仍然愿意在数据库设计领域使用数据建模与数据模型的名称,我们在这一章也使用数据建模与数据模型。具体使用哪一种命名不会影响数据库设计的结果,只是需要注意的是这里的数据模型与DBMS数据库模型的不同。
本章主要讨论数据建模,而且主要讨论数据建模中的逻辑设计,而对物理设计只作一些简单的讨论。这样做是基于以下的考虑:
 数据建模是数据库设计的核心阶段,数据库设计所完成的大部分工作是数据建模。
 逻辑设计是物理设计的基础,它有一些常用的方法,如本章所介绍的IDEF1X方法,而物理设计则是依赖于某一个特定的DBMS,没有一个通用的方法,依不同的DBMS有着不同的物理设计方法。
数据建模有许多方法,这些方法大都是以Peter Pin-Shan Chen在1976年提出的实体联系模型为基础修改而来的。本章介绍的方法是美国空军IDEF建模方法中的数据建模方法IDEF1X。
6.2. IDEF1X方法
IDEF分析方法统称为IDEF(IDEF是Integration DEFinition的缩写),它是70年代中期美国空军的ICAM(Integration Computer Aided Manufacturing)计划下所发展出来的一套系统分析与设计的工具,功能模块分别为IDEF0、IDEF1、IDEF1X、IDEF2至IDEF14系列家族。ICAM计划的宗旨是通过系统地应用计算机技术来提高机械制造业的生产率。ICAM认为:对于想要提高生产率的人员来说,需要一个好的分析和通讯技术(交流技术)。所以ICAM计划开发了一系列的IDEF方法。最初阶段,这一系列方法只包括3种不同的建模方法,这3种方法用图形方式来刻画整个制造业环境系统。
 IDEF0 功能建模(Function Modeling)
 IDEF1 信息建模(Information Modeling)
 IDEF2 仿真建模设计(Simulation Modeling Design)
1983年美国空军ICAM计划着手IISS(Integrated Information Support System)项目。此项目的目的是提供一套能在逻辑上和物理上集成异种计算机硬件和软件的技术。IISS把集成的途径放在数据源单一语义定义的获取、管理和使用上,这个“概念模型”(conceptual model)是用IDEF1建模技术来定义的。
IDEF1X(Data Modeling)把实体-联系方法应用到语义数据模型中。IDEF1的最初形式是在P.P.S(Peter)Chen的实体联系模型化概念与P.P.(Ted)Codd的关系理论的基础上发展而来的。IDEF1X对IDEF1做了一些改进,增强了图形表达能力,丰富了语义(如分类联系的引入)和简化了开发过程。自1980年以来,IDEF1X已在应用中得到发展和验证。IDEF1X在数据建模方法具有如下的特点:
 支持概念模式的开发
IDEF1X语法支持概念模式开发所需的语义结构,完善的IDEF1X模型具有以下所期望的一致性、可扩展性和可转换性。
 是一种一致性的语言
IDEF1X有关简洁、一致的结构,以及独特的语义概念。IDEF1X的语法和语义简单且功能强大、健壮。
 IDEF1X是可教授的
语义数据建模对于许多IDEF1X的用户来说是一种新的概念,所以语言的可教授性是重点考虑的一个方面。语言可以教授给数据库管理员、数据库设计者使用,同样也可以教授给业务专家、系统分析员使用。因此,它可以作为一个跨学科领域的有效沟通工具。
 经过良好的测试和验证
IDEF1X是基于前人多年的经验发展而来的,它在美国空军和民菅的一些项目中充分地得到了检验和证明。
 可以自动化
IDEF1X图能由软件生成。许多商业软件支持IDEF1X模型的分析、求精和配置管理。例如,CA公司的ERwin Data Modeler数据建模工具。
6.2.1. IDEF1X数据建模方法论
从三层模式的描述得知,数据建模的过程就是将外部模式用概念模式表示出来,形成一致的数据定义,为内部模式的生成提供便利。然而,这个过程涉及的因素很多,也很复杂。人们常常使用分层的方法来使复杂的问题得以简化,数据建模过程也不例外。IDEF1X也提供了多层次建模思想,以便于逐步建立和细化数据模型。下面介绍了5个层次的模型。在实践中,不必拘泥于这几个层次,你会发现根据各自不同的情况扩展或者缩减模型的层次有助于问题的解决。
图 6 2 IDEF1X数据模型的层次
最高层的模型分为两种:实体-联系图(Entity Relationship Diagram,简称ERD)和基于键的模型(Key-Based,简称KB)。ERD标识了主要的业务实体和它们之间的联系。KB模型建立了业务信息需求的范围(包含所有实体)并开始逐步揭示细节。
低层模型也分为两种形式:全属性模型(Fully Attributed,简称FA)和转换模型(Transformation Model,简称TM)。FA模型是符合第三范式的,其中包含了为特定实现工作的所有逻辑细节。转换模型代表了从关系模型到所选的特定DBMS实现结构之间的转换信息。
在多数情况下,转换模型是不满足第三范式的。模型的结构已经针对特定DBMS的性能、数据容量、期望的数据访问模式和性能进行了优化。
逻辑模型
逻辑模型用于捕获业务信息需求,有三个层次:实体-联系图、基于键的模型和全属性模型。ERD和KB也称为“领域数据模型”,因为这种模型所覆盖的范围经常是一个较大的业务领域,比一个项目要实现的范围广。相反,FA模型是一个“项目数据模型”,因为这种模型经常是描述整个数据结构的一部分,用于某一个单一的项目。
实体联系模型是一种高层次数据模型,用来表示主要的实体及它们之间的联系,它不只是用于数据库系统还可以用于更广泛的业务领域。这种模型的目的主要是用于展示或者讨论。
实体-联系模型是用来提供一种业务信息需求的视图,能够满足系统开发的粗略需求即可,它不包含如属性信息等许多具体的细节。在模型中使用的联系可以是不确定的联系(多对多联系)。
基于键的模型描述主要的数据结构,也适用于广泛的业务领域。这种模型应该包含所有的实体和主键,并且包含一些主要的或示例属性。这种模型的目的是给出大致的数据结构和主键的业务视图,并为进一步细化模型提供基础。它的覆盖领域与ERD模型相同,但是展现了更多的细节。
全属性模型是一个符合第三范式的数据模型,它包含一个项目实现所需要的全部实体、属性和联系。这种模型还包括实体实例的容量、访问路径和比率,以对数据结构所期望的交易访问模式。
物理模型
物理模型包含用于实现的两个层次:转换模型和DBMS模型。物理模型要捕获所有系统开发的信息,这些信息让开发者可以理解逻辑模型,并将其实现为数据库。转换模型也是个“项目数据模型”,描述整个数据结构的一部分。
转换模型的目的是为数据库管理员创建高效的物理数据库提供充分的信息,并为定义和记录用于向数据字典生成数据库的数据元素和记录提供一个上下文环境,同时为应用开发团队编制用于访问数据的程序提供物理数据结构。
转换模型还为开发团队提供比较物理数据库设计和初始业务信息需求之间的异同。
转换模型被直接翻译成DBMS模型。DBMS模型记录位于DBMS模式或系统表之中的物理数据库对象的定义。
6.2.2. IDEF1X的语法和语义
实体
实体(entity)是现实世界中具有一组相同属性的“事务”或“对象”的集合,集合中的每个元素称为实体的实例(entity instance)。例如,企业中的员工就是一个实体,而每一个员工是员工实体中的一个实例,它与其它所有的员工具有相同的属性,如姓名、性别、年龄等。
有些教科书中将实体与实例分别解释为实体集与实体。现实的情况是在数据建模领域中,有关的术语的定义还不是十分精确,没有一个统一的标准,你不必过分细究这些术语。
实体有两种类型,分别是独立标识实体(Identifier-Independent Entities,简称独立实体)及可从属标识实体(Identifier-Dependent Entities,简称从属实体)。有时,也将“独立实体”与“从属实体”分别称为“强实体”与“弱实体”。例如,图 6 3中的部门实体与员工实体都是独立实体,而图 6 4中员工实体是独立实体,它不需要其它实体的关系就可以标识一个员工,如通过员工实体中的员工编号能够唯一标识一个员工,而员工工资实体(假如将员工的工资单独设置为一个实体)则是从属实体,它的一个实例必须由员工实体的一个实例标识,如果相应的员工实例不存在,则该员工工资实例也不存在。
在IDEF1X中,独立实体用四边形表示,从属实体用带圆角的四边形表示。每个实体分配一个唯一的名字。实体名应当是一个名词或名词短语,这个名词或名词短语应该是单数而不是复数,且允许使用缩写,但实体名应当是有意义的,且在整个模型中保持一致。
图 6 3 独立实体

图 6 4 独立实体与从属实体
IDEF1X关于实体规则定义如下:
 每一个实体必须使用唯一的实体名,相同的含义必须总是用于同一实体名。
 一个实体可以有一个或多个属性,这些属性可以是实体自身所具有的,也可以是通过一个联系而继承得到的。
 一个实体应有一个或多个能唯一标识实体中每一个实例的属性(主关键字和次关键字)。
 任意实体都可以与模型中其它的实体有0个、1个或多个联系。
 如果一个外键是一个主键的全部或部分,那么该实体就是从属实体。相反地,如果根本没有外键属性用作一个实体的主键,那么这个实体就是独立实体。
属性
一个“属性”表示一类现实或抽象的事务的一种特征或性质(如:人、物、地点、事件、概念等)。在IDEF1X模型中,属性是与具体的实体相联系的。实体的每一个相关属性都必须具有一个单一且确定的值。例如,员工姓名、年龄和性别是与员工实体相关的属性。
IDEF1X关于属性的语法规定:每个属性都必须有一个唯一的名称来标记,这个名称用一个名词或名词短语来表示,它描述了属性所表述的实体特征。名词或名词短语采用单数而不是复数形式。
在实体的四边形内,属性被列出且每一行只有一个属性,主键属性被放在列表的最上面,且用水平线将它与其它属性分开,如图 6 3所示。
每个属性都有一个可取值的范围,称为该属性的域(domain)或者值集(value set)。员工姓名的域是一定长度或可变长度的字符串集合,类似地,员工生日属性的域是一个日期类型的值的集合。
主键
一个实体必须具有一个属性或属性组,其值唯一地确定该实体中的每一个实例,这些属性或属性组称为侯选键或侯选码。例如,员工实体中的员工编号和员工的身份证号都可以唯一地确定一个员工,它们都是侯选键。一个实体中可能会有一个或多个这样的侯选键,在创建模型时必须选择其中的一个作为主健(primary key)。实体中的任意两个不同的实例都不允许同时在键属性上具有相同的值。
主键的选择应该是那些从不或极少变化的属性。例如,员工的地址就不该作为主键的一部分,因为它很可能变化。而身份证号不变,可以作为主键,但你要保证实体中的每个实例都具有身份证号,如果是一个跨国公司,由于有些员工没有身份证号,因此身份证号不能作为员工实体的键,当然也不能作为主键。
确定性联系
一个确定性联系(specific connection relationship)或简称联系(relationship)是指实体间的相互关联。在这种联系中,被称为父实体的每一个实例都与子实体的0个、1个或多个实例相关联。例如,员工实体与部门实体相互关联,我们可以定义员工“张三”属于部门“销售部”,而部门“销售部”拥有员工实体中的员工“张三”等。其中,部门实体是父实体,员工实体是子实体。
联系有三个属性:名称、基数(cardinality,有时也称为度量)和联系的类型(标识或者非标识、非空)。除此以外,联系还是双向的,命名、设置基数和类型都需要在两个方向上进行。
联系的名称使用动词或动词短语而不是使用名词进行命名,如员工与部门实体的联系的名称可以命名为“属于”,而部门与员工实体的联系可以命名为“拥有”。
联系的类型指的是联系是标识联系或非标识联系,以及子实体中的实例中与父实体对应的值是否可以为空。例如,上面员工实体与部门实体的联系,如果员工实体中的部门编号可以空,则表示该员工不属于任何一个部门(可能是新入职还未分配部门的员工)。
在IDEF1X中,能够表示下列不同基数的联系:
 图(1)表示每一个父实体实例与0个、1个或是多个子实体的实例相关联。
 图(2)(黑色圆点旁有一个P)表示父实体的每一个实例至少与1个或多个子实体的实例相关联。
 图(3)(黑色圆点旁有一个Z)表示父实体的每一个实例与0个、1个子实体的实例相关联。
 图(4)(黑色圆点旁有一个n)表示父实体的每一个实例与特定数量的子实体实例相关联。
 图(5)(黑色圆点旁有一个n-m)表示父实体的每一个实例与一定范围的子实体的实例相关联。
 图(6)(黑色圆点旁有一个(n) ,其中n是一个表达式)表示父实体的每一个实例与满足一定条件的子实体的实例相关联。例如条件为:大于3、必定是7或是9。
图 6 5 IDEF1X中的联系类型
标识联系与非标识联系
确定性联系又可以划分为标识联系与非标识联系。
标识联系是这样一种联系,子实体的一个实例通过父实体标识,即子实体依赖于父实体而不能单独存在。也可以解释为父实体的主码在子实体中既是外码又是主码的一部分或全部。如图 6 6所示,
图 6 6标识联系
对于非标识联系,父实体中的主码在子实体中仅作为外码。如图 6 7所示
在图 6 7中,产品编号PRODUCT_ID可以作为主码唯一标识一个产品,它有一个前提是所有厂商的所有产品都有唯一的编号,如果这个前提不成立,而只能够满足同一厂商的所有产品具有唯一的产品编号,那就需要使用图 6 6中的标识联系。什么时候使用标识联系什么时候选择非标识联系完全取决于实际应用。

图 6 7非标识联系
分类联系
当多个实体有共同的属性时,而这些实体又分别有一些不同的属性时,可以创建一个一般实体并将这些实体共同的属性作为一般实体的属性,如银行应用中的储蓄账号、支票账号和贷款账号,其中都有开户人姓名、开户时间这两个属性,而这些实体又都各自有一些特殊的属性,在数据建模过程中可以使用分类联系进行处理,如

图 6 8 完全分类联系
这里,账户实体是一般实体,支票账户、存款账户和贷款账户是分类实体。
完全分类联系是两个或多个实体间的联系,且在这些实体中,存在一个一般实体,它的每一个实例都恰好与一个且仅一个分类实体的一个实例相联系。在完全分类联系中,一般实体的每一个实例和与之相关的一个分类实体实例描述的是现实世界的同一个事务,因此它们具有相同的唯一标识符。例如,账户实体与支票账户、存款账户和贷款账户实体的联系是一个完全分类联系,一般实体“账户”中的一个实例账户编号为002010997如果与存款账户实体对应,则存款账户实体中必有一个账户号同为002010997的实例,这两个实例描述的是同一个账户的不同部分。
对于同一个一般实体的分类实体总是互不相容的,也就是,一般实体的一个实例只能与一个分类实体的一个实例相对应。在上例中意味着一个账户不可能既是支票账户又是存款账户。
此外,IDEF1X语法还允许不完全分类的情况出现,如存在一般实体的一个实例不与任何分类实体中的任何实例相关联,那么,这个联系就被定义为“不完全分类联系”。完全分类与不完全分类的图形表示方法也不同,它们的主要差异是鉴别器的不同。上面的例子是一个完全分类联系,而不完全分类联系的表示方法如下:
图 6 9 不完全分类联系
在一般实体中的一个属性确定一般实体与分类实体的联系,这个属性被称为分类联系的“鉴别器”。在上面的例子中,账户类型为鉴别器。
非确定联系(多对多联系)
确定性联系与分类联系都确切地定义了一个实体的实例是如何与另一个实体的实例相关联的。在完善的IDEF1X模型中,实体间的所有联系都必须用确定联系(包括分类联系)来描述。但是,在建模的初级阶段,只需要发现实体间有没有联系即可,至于到底是哪种类型的联系并不重要。只要通过分析知道两个实体间存在联系,就可以将其描述为 “非确定联系”(non-specific relationship)。两个实体间的非确定联系通常称为多对多联系。它用来表示第一个实体的一个实例与另一个实体的多个实例都相关联,相反,第二个实体中的一个实例又与第一个实体中的多个实例相关联。例如,客户实体与产品实体有联系,一个客户可以购买多个产品,即客户实体中的一个实例可以与产品实体中的多个实例相关联,反过来,一个产品(指一种产品,如某型号电视)可以销售给多个客户,即产品实体中的一个实例与客户实体中的多个实例相关联。它在IDEF1X中的表示方法如下:
图 6 10 多对多联系
多对多联系常用在数据模型开发的早期阶段。因为多对多联系常常隐含了某些业务规则,因此,多对多联系应当在随后的建模过程中进一步细化以明确隐含的业务规则。通常的做法是引入一个新的实体作为原来两个实体的中间联系实体,将多对多的联系分解成两个一对多的联系。例如,上面的客户和产品的多对多联系可以通过引入一个产品销售明细或产品销售清单进而使原来的多对多联系得到分解。
图 6 11 多对多联系的分解
外键
如果在两个实体之间存在确定联系或分类联系,那么构成父实体或一般实体主键的属性被迁移到子实体或分类实体的属性,这些迁移属性被称为“外键”。例如,在图 6 3的示例中,父实体“部门”的主键属性“部门编号”被迁移到子实体“员工”的属性,在“员工”实体中,属性“部门编号”是迁移属性或外键(foreign key)。
一个外键可以在一个实体中作为部分或全部主键属性或非键属性。在图 6 4的示例中,“员工工资”实体中的外键“员工编号”也是实体的主键,而图 6 6的示例中,子实体“产品”的外键“厂商编号”只是主键的一部分。
外键是通过把迁移属性名加“FK”标注进行描述。如果迁移属性属于子实体的主键,那么该迁移属性被放在水平线上面并且这个实体使用带圆角的四边形表示(从属实体)。
角色
实体在联系中的作用称为实体的角色(role),它是通过迁移属性体现的。由于参与一个联系的实体通常是互异的,角色是隐含的并且不需要指定。例如,在图 6 3的示例中,迁移属性“部门编号”在实体“员工”中的作用是标识员工所在的部门,迁移属性本身已经隐含了这一作用,因此并不需要明确指定。但是,当参与联系的实体并非互异的时候,也就是说,一个实体作为父实体与同一个子实体有多个联系的时候,则父实体每次参与联系都有不同的角色。例如,在下面的示例中,“员工”实体与“合同”实体有两个联系,在第一个联系中,迁移属性“员工编号”的作用是“销售”,第二个联系中,迁移属性“员工编号”的作用是“技术审核”,在IDEF1X的表示中,必须为迁移属性的角色命名且角色名是唯一的。
图 6 12 相同父实体和子实体有多个联系的角色
另外一种需要定义角色的情况是递归联系(实体到实体自身的联系),如图 6 13所示,“员工”实体中的“部门经理”是一个角色名,它是该员工的部门经理的员工编号。
图 6 13在递归联系中的角色
定义角色就是给外键属性重新命名,如果没有定义角色,外键属性的名称就是父实体中主键的属性名。
6.2.3. 建立模型过程
设计的开始

定义实体
1阶段的目标是标识和定义在建模的问题范围中的实体,这个过程的第一步是标识实体。
开始时,标识实体是一个随心所欲的过程,在你试图标识和捕获系统中潜在的实体时,没有愚蠢的问题或沉默的思想。在新的系统中,寻找新系统描述和旧系统、旧系统报告以及与用户的交流中的名词作为潜在实体的来源,这里的方法是捕获尽可能多的潜在实体,然后在建模过程中清除无用实体。对最初出现的实体应该耐心,有些实体看起来可能没有什么用处,但你还是应该保留它们直到确认它们应该被删除为止,也许这些你认为没有什么用途的实体在后续的建模过程中会显现出它们的作用。
有人建议在初始建模时将所有的交流过程中出现的名词都作为实体,然后对这些实体在建模的过程中逐步求精。对于一个小型的系统,这种做法不会遇到什么困难,但采用它去处理复杂系统时就会变得不可行,因为,出现的名词可能会有数百甚至上千,有些名词很明显地不需要标识为一个实体或者与其它的名词可以一起标识为一个实体。因此,在实际的建模过程中应视具体的情况灵活运用而不是教条地按方法执行。
在一个大的企业系统中开发应用程序时(你的应用程序与其它应用程序在一个公共的数据库环境下共存),在过程的早期,你需要为实体提出一个命名约定以避免对象的冲突并使系统保持一致性。如果没有一个统一的约定,不同的开发者在命名实体时就会按完全不同的方式进行。
命名约定不仅对实体是必须是,对于其它的对象,包括属性、联系、约束等所有的对象都是必须的。
建立数据模型的第一步是捕获在数据模型中代表所有的业务对象的无约束的实体组,然后将它添加到实体联系模型中。经过一段时间后,当你使用这些数据模型时,这些实体就会得到逐步的完善。当这个过程继续的时候,你发现你自己正在创建、删除和修改模型中的实体,以使它们符合业务需求。
标识实体时一个有用的经验是将业务信息分解成几个大的部分,然后对每一个部分分别进行标识,且在标识实体时最好是先标识基本信息的实体,然后再标识动态信息的实体。基本信息指的是在业务运行过程中信息基本保持不变的信息,而动态信息是随着业务的运行随时发生变化的信息,也可以称为静态信息(不是完全不变)和动态信息。例如,在合同管理系统的数据模型过程中,可以把业务信息划分成组织机构、客户、产品、合同几个部分,其中,组织机构可以由部门、员工信息组成,客户由客户单位和联系人信息组成,产品由产品和厂商信息等组成,这些信息都属于基本信息,在合同的管理过程中很少发生变化,你可以先将这些基本信息中的实体标识出来得到:部门、员工、客户单位、客户联系人、厂商、产品等实体。而合同信息则基本上是由动态信息组成的,在标识基本信息实体后再标识这一部分信息中所含的实体,可能只有合同实体,以后会细化成多个实体。这一示例虽然简单,但它给我们展示了在将信息划分为几个部分时如果划分得当,问题的复杂性就会降低。
定义联系
联系存在吗?这看似是一个并不复杂的问题。例如,在你初步标识完合同管理系统中的实体后得到的实体是:部门、员工、客户单位、客户联系人、厂商、产品、合同,那么这些实体两两之间哪些有联系呢?你会发现这些实体两两之间绝大多数都有联系,如果按照这样对联系的定义去构造一个数据模型,你会得到21个联系,如果有50个实体,你会得到1225个联系,这些联系会使表示模型的ERD无法辩认。因此,如何区分哪些是必要的联系,哪些是不必要的联系是很重的,也有一定的难度。
部门和员工之间的联系是必然联系,那么员工和客户有联系吗?有!但不是必然联系,它是通过销售这一业务活动建立联系的,而销售活动是通过合同体现的,因此,它们之间的联系是通过合同建立的。部门与合同是否有联系呢?有!但这个联系是通过员工的销售活动建立的,因此,它们之间的联系是通过员工建立的。继续分析你会发现,有些实体之间有直接的联系,而有一些实体之间虽然有联系但不是直接的联系。这样,我们就可以得到下面的实体-联系模型。
图 6 14 合同管理系统实体-联系模型
具体哪些实体之间有直接的联系,哪些实体之间没有直接的联系,要根据具体的业务需求确定,并非一成不变。例如,在上面给出的合同管理系统的示例中,如果需要记录客户信息是由哪一个销售人员维护的,则客户与员工就有直接的联系。
在模型的开发初期,不可能将全部联系表示成父子联系或分类联系。因而,在该阶段中,允许定义非确定的联系。
在标识联系后的下一步是定义确定联系的属性,对于不确定联系,只有等不确定联系分解为确定联系后再进行定义。定义联系的属性包括:联系名、联系的基数和联系的类型(标识或非标识、非空),这些属性都是双向的。例如,在上面的示例中,部门和员工实体间的联系从部门到员工的方向的联系名定义为“拥有”、联系的基数是0个、1个或多个、联系的类型是非标识联系且非空。
联系的定义完成后,需要对定义的联系进行验证,验证也是在两个方向上进行的。例如,上面示例中部门与员工的联系可以用下面的方法进行验证:
 一个部门可以拥有1个或多个员工;
 一个员工必须属于1个且只能属于1个部门。
产品部分有厂商和产品两个实体,厂商是父实体,产品是子实体,它们的联系是生产与被生产的联系。
组织机构信息与合同信息之间有员工负责销售(是该合同的销售负责人)、员工对合同进行技术审核、员工对合同进行商务审核、员工在合同签字等。其中,给出的示例略去了员工在合同上签字这一联系。
客户签订合同。
合同订购产品。
根据上面的分析,确定员工与合同实体有三个联系:销售负责、商务审核和技术审核;客户与合同有一个联系:签订合同;合同与产品有一个联系:订购产品。
从上面的分析可以看出,联系是基于业务活动确定的。但并不是所有的业务活动都需要建立联系,一些次要的业务活动被忽略,一些业务活动通过间接联系体现。确定联系的难点是哪些联系在数据模型中体现而哪些联系通过间接联系体现,哪些又被忽略。准确的确定联系是构造一个高质量数据模型最重要的部分之一,除此之外还有实体和属性的确定。这些只能通过充分分析应用需求并加以丰富的经验才能达到。
定义键

定义属性
这一阶段的目标是:
 开发属性池;
 建立属性的所有者关系;
 定义非键属性;
 确认并改进数据结构。
(1) 如何处理付款信息
每一个合同可能有多个付款阶段,如何记录付款信息可以有两种方案:一是直接在合同实体中设置多个属性,比如付款一、付款二、付款三等,如果一个合同有更多的付款阶段这些属性仍无法记录付款信息;另一种方案是单独设置一个“付款”实体,在付款实体中记录合同的付款信息,设置的属性可以有应付款数量、应付款日期。显然,后一种方案比前一种方案更有效。
仔细分析发现,除了合同中的应付款信息还有合同的已付款信息。在实际应用中,应付款项和已付款项并不是一一对应的。比如,合同中应付款项有三项,但客户有可能一次或两次就将款项付清。处理这种情况可以在付款实体中再设置一个付款类型属性,用于区别是应付款项还是已付款项,也可以再设置一个“已付款”实体。在给出的示例中是用两个单独的实体PAYMENT和PAID表示应付款信息和已付款信息。这样,当需要查询一个合同中的已付款信息时就可以根据PAYMENT中的合同编号CONTRACT_ID获得,如下的命令可以查询每一项合同的应付款总额,
图 6 15 查询每一项合同的应付款总额
如何需要查询还有哪些合同未完成付款,输出对应的销售人员姓名和合同编号,则可以使用下面的查询,
图 6 16 查询未完成付款的合同
(2) 如何处理合同中的产品信息
一个合同中会订购多个产品,记录的信息有产品的编号、产品的数量和产品的价格。这里为什么要记录产品的价格呢?它不是可以从产品的基本信息实体中查询得到吗?这是因为产品基本信息中的产品价格是不断变化的,合同签订时的产品价格可以从产品信息表中查询,但随着时间的变化,产品信息中的价格就发生了变化,因此,需要合同信息中记录产品当时的销售价格。另外,为了如实反映产品的价格情况,在示例中使用产品的公开价格和折扣两个属性。
与合同的付款信息类似,在示例中使用一个单独的实体“CONTRACT_PRODUCT”存储合同的产品信息。
(3) 如何处理订单信息
在示例中,我们使用了两个实体“ORDER_HEADER”和“ORDER_DETAIL”记录订单信息,分别表示订单概要信息和订单明细。在订单概要信息实体中记录订单的基本信息如订单的日期等,在订单明细中记录订单的产品信息。
可能会有人提出这样的问题,订单的产品不是可以从合同的产品中查询得到吗?假如这样处理,其前提是合同中的产品与订单中的产品是一一对应的。但实际情况并不总是这样,比如,有时合同中的产品是公司已经有的产品(可能是以前购买,也可能是自己生产的等)。因此,示例中的处理方法使得数据模型能够更好的满足实际应用的需求。
6.3. ERwin数据建模
6.3.1. 建立实体联系
在ERwin中建立实体联系的步骤如下:
(1) 选择工具栏 中的非标识联系按钮,其中, 是实体, 是分类联系, 是标识联系, 是多对多联系, 是非标识联系。
(2) 点击父实体。
(3) 点击子实体。使用联系连接两个实体后,父实体的主码会自动成为子实体的外码,如图 6 17。
图 6 17 实体的联系
(4) 双击联系连接线进入联系属性对话框(图 6 18),在对话框的“General”面板的“Verb Phrase”中设置联系的名称,将父实体到子实体的联系名称设置为“销售”,子实体到父实体的联系名称设置为空。右下角的联系类型“Relationship Type”的空值属性设置为“No Nulls”,它表示子实体中的外码不能为空值。
图 6 18 联系属性对话框
点击OK后显示如下的结果。
图 6 19 实体联系的非空约束
注意连接父实体一端的棱形消失了,父实体一端变成了单线。在窗口的空白处点击右键弹出菜单选择“Relationship Display/Verb Phrase”显示联系的名称,结果如下:
图 6 20 显示联系的名称
6.3.2. 两个实体的多个联系的处理
当使用联系连接两个实体后,父实体的主码会自动成为子实体的外码。对于只有一种连接联系的两个实体这样可以不用再做其它的处理。但如果两个实体有多个连接联系则必须采用其它的方法。比如,合同管理系统中员工实体与合同实体,每一个合同必须有一个销售负责人(负责销售联系),每一个合同还必须有一个商务审核(商务审核联系),每一个合同还必须有一个技术审核(技术审核联系)等,这样,员工与合同实体就存在三个连接联系。创建两个实体的多种联系需要通过逻辑模型中的角色来完成。下面的步骤演示了如何创建员工实体与合同实体的负责销售联系和商务审核联系。
(1) 建立员工实体EMPLOYEE与合同实体的联系
图 6 21 员工与合同的第一个联系

(2) 设置合同实体中外码EMPLOYEE_ID的角色名,在逻辑模型中双击两个实体间的联系进入联系的属性对话框(图 6 22),

图 6 22 设置联系的角色名
(3) 在对话框(图 6 22)中选择Rolename(角色名)然后在下面的Rolename文本框中输入角色名SALE_ID,点击OK。完成后的实体联系如图 6 23所示,注意原来的外码名称EMPLOYEE_ID变成了SALE_ID。
图 6 23 员工与合同的销售联系
(4) 建立第二个联系。在完成上面的操作后我们可以建立第二个联系,如图 6 24所示,
图 6 24 创建员工与合同的第二个联系
注意图中两个联系边线中下面的一个是新创建的联系。但这并不是说新创建的联系都会放置在原有联系的下面,可以通过双击联系连线打开联系属性对话框进行检查或通过给联系命名并显示联系的名称来判断联系。
(5) 可以通过角色名将新建的联系修改如下,
图 6 25 员工与合同的销售与商务审核联系
6.3.3. 递归联系
递归联系又称自反联系,是实体与实体本身的联系。创建递归联系的步骤如下:
(1) 选择非标识联系工具。
(2) 点击实体。
(3) 再次点击实体,如果如图所示。
图 6 26 员工实体的递归联系
(4) 设置联系的角色名为MANAGER_ID,表示该员工的部门经理,结果如下:
图 6 27 设置员工实体递归联系的角色名
6.3.4. 分类联系

图 6 28 分类联系
创建如上分类联系的具体步骤如下:
(1) 创建“账户”“支票账户”“存款账户”“贷款账户”四个实体和相应的属性,在子类实体中不要创建其主码“账户号”,它会由父类实体自动迁移到子类实体中。
(2) 选择分类联系并点击父类实体和子类实体“支票账户”,建立联系后的结果如下:
图 6 29 建立账户与支票账户的分类联系

(3) 双击上图中的分类联系图符进入到分类联系属性对话框,在对话框中选择分类属性为“账户类型”,点击“确定”后结果如下:
图 6 30 分类联系属性对话框

图 6 31 选择分类属性后的分类联系
(4) 再次选择分类联系,点击分类联系(注意这次不是点击父实体)然后点击子类实体“存款账户”建立“账户”与“存款账户”的分类联系。使用同样的方法完成“账户”到“贷款账户”的分类联系的建立。完成后如前面图 6 28所示。
6.3.5. 使用域简化数据类型的设置
“域”在数据库中表示属性的取值范围,但在ERwin中域是一个用户定义的新的数据类型,该数据类型是使用基本类型定义的。如果在多个实体中定义了具有相同数据类型的属性,可以使用域简化数据类型的定义。例如,厂商、客户、部门实体中的名称和通信地址都具有相同的数据类型,如果定义一个域NAME其数据类型为可变长的字符串且长度为32即VARCHAR(32),然后可以使用域NAME定义厂商、客户和部门的名称属性的数据类型。如果发现VARCHAR(32)的数据类型需要修改时,直接修改域NAME的数据类型则直接导致所有使用域NAME定义的属性的数据类型。
在模型导航器窗口中选择域“Domains”,单击右键弹出菜单并选择“New”创建一个新的域,将域名修改为NAME,如所示:
图 6 32 定义域NAME
图 6 33 域的属性对话框
双击域NAME打开域属性对话框(图 6 33),将域的数据类型设置成VARCHAR(32)即完成域的设置。
在定义实体属性的数据类型时就可以使用新创建的域,例如,定义客户的单位名称时,在实体属性的属性对话框中选择域NAME,如图 6 34所示:
图 6 34 实体属性对话框

6.3.6. 将数据模型导入到数据库
在完成数据模型的设计后就可以将物理数据模型导入到某一个数据库管理系统中,ERwin支持某前大多数主流的数据库管理系统,具体的支持情况视不同的版本有些区别。如ERwin 4.0的版本不支持SQL Server 2005,但可以将生成的SQL语句拷贝到SQL Server 2005的查询分析器直接执行或保存到一个文本文件再到查询分析器去执行。如果是ERwin 7则支持SQL Server 2005,但前提是运行ERwin的系统上必须安装SQL Server 2000的客户端或安装文件NTWDBLIB.DLL文件到Windows的System32目录下。可以到http://www.cnblogs.com/Files/skywind/ntwdblib.rar下载该文件。
下面给出的具体步骤演示了如何将合同管理数据模型导入到SQl Server 2005的CONTRACT数据库中,具体的步骤如下:
(1) 在SQL Server中创建数据库CONTRACT。
(2) 在ERwin中将数据模型切换到物理模型,只有物理模型才可以导入到数据库中。
(3) 在ERwin中选择“Database/Database Connection”连接数据库,选择使用Windows身份验证模式,输入数据库名为CONTRACT,数据库的服务器名为GUO(如果是有名实例,如实例名为CCBIT,则数据库服务器的名称为GUO\CCBIT),完成后点击“Connect”。
图 6 35 连接SQL Server数据库

(4) 选择Tools/Forward Engineer/Schema Generation,如下所示,
图 6 36 导入数据模型的菜单
执行后会打开“Forward Engineer Schema Generation”(正向工程模式生成)对话框,在该对话框中可以直接点击“Generate”在连接的数据库中生成数据模型,也可以在点击“Preview”预览生成数据模型的SQL语句,如果ERwin不支持某个数据库版本的连接则可以将预览窗口(图 6 37)中的SQL文本拷贝到相应的地方或保存到一个文本文件去执行。
(5) 点击模式生成对话框中或预览对话框中的“Generate”将数据模型导入到数据库中,如果执行成功则结果如所示,

图 6 37 预览数据模型的导入
图 6 38 成功导入数据模型
在将模型生成到SQL Server目标数据库时,ERwin生成的T-SQL语句中有错误代码“raiseerror @errno @errmsg”,这些错误代码出现在某些Erwin自动生成的触发器代码中。修正这些错误的方法有两个,一是修改该语句的错误(RAISEERROR的详细说明参见书中前面的内容或联机文档),二是禁止ERwin自动生成触发器。禁止Erwin生成触发器如下图所示:

6.4. 合同管理系统数据建模示例
本节对合同管理系统的数据模型建模过程进行说明,建议在阅读本节前先阅读“合同管理应用需求描述”一章的内容,必须要了解应用需求才能理解本节的内容。完整的数据模型如下:
图 6 40 合同管理系统数据模型
6.4.1. 实体的确定
首先确定的是基本的实体。在合同管理系统中,信息有几个基本的组成部分:公司、客户和产品。描述一个公司,可以使用“部门”和“员工”两个实体;描述客户可以使用“客户”一个实体;描述产品信息需要“厂商”和“产品”两个实体。这些都是基本实体,即在业务活动中变化较少的实体,我们也可以把它们称为静态实体。
当然,上面的基本实体的确定都是最简单的,如果要考虑得更完整,则还需要一些其它的实体。如客户信息中必须包含有客户联系人,而在实际应用中客户的联系人会有多个,因此还需要有一个“联系人”实体,只不过我们在这里将这些问题简化了。
在确定完基本的实体后,就是确定合同信息的有关实体。合同信息中有很多内容,难以用一个实体来表示。但现在不急于将这些实体细化,我们先考虑主要的实体。
6.4.2. 联系的确定
在确定完主要的实体后,就是确定这些实体的联系。基本的原则是先局部后整体,先考虑公司、客户、产品这三部分,然后再考虑它们相互之间及它们与合同的联系。
公司信息部分的实体只有两个:部门和员工,很明显,部门是父实体,员工是子实体。它们之间是属于和拥有的联系。但在这里没有给出联系的名称,因为这并不是创建模型所必须的。但在复杂数据模型的设计中,为联系命名有助于提高数据模型的质量。
客户信息部分的实体只有一个,因此不用处理。
产品部分有厂商和产品两个实体,厂商是父实体,产品是子实体,它们的联系是生产与被生产的联系。
公司信息与合同信息之间有员工负责销售(是该合同的销售负责人)、员工对合同进行技术审核、员工对合同进行商务审核、员工在合同签字等。其中,给出的示例略去了员工在合同上签字这一联系。
客户签订合同。
合同订购产品。
根据上面的分析,确定员工与合同实体有三个联系:销售负责、商务审核和技术审核;客户与合同有一个联系:签订合同;合同与产品有一个联系:订购产品。
从上面的分析可以看出,联系是基于业务活动确定的。但并不是所有的业务活动都需要建立联系,一些次要的业务活动被忽略,一些业务活动通过间接联系体现。确定联系的难点是哪些联系在数据模型中体现而哪些联系通过间接联系体现,哪些又被忽略。准确的确定联系是构造一个高质量数据模型最重要的部分之一,除此之外还有实体和属性的确定。这些只能通过充分分析应用需求并加以丰富的经验才能达到。
6.4.3. 确定属性
确定基本实体的属性比较简单,但合同实体的属性就必须要作进一步的分析才能确定。
6.4.4. 如何处理付款信息
每一个合同可能有多个付款阶段,如何记录付款信息可以有两种方案:一是直接在合同实体中设置多个属性,比如付款一、付款二、付款三等,如果一个合同有更多的付款阶段这些属性仍无法记录付款信息;另一种方案是单独设置一个“付款”实体,在付款实体中记录合同的付款信息,设置的属性可以有应付款数量、应付款日期。显示后一种方案比前一种方案更有效。
仔细分析发现,除了合同中的应付款信息还有合同的已付款信息。在实际应用中,应付款项和已付款项并不是一一对应的。比如,合同中应付款项有三项,但客户有可能一次或两次就将款项付清。处理这种情况可以在付款实体中再设置一个付款类型属性,用于区别是应付款项还是已付款项,也可以再设置一个“已付款”实体。在给出的示例中是用两个单独的实体PAYMENT和RECEIVED_PAY表示应付款信息和已付款信息。这样,当需要查询一个合同中的已付款信息时就可以根据PAYMENT中的合同编号CONTRACT_ID获得,如下的命令可以查询每一项合同的应付款总额,
图 6 41 查询每一项合同的应付款总额
如何需要查询还有哪些合同未完成付款,输出对应的销售人员姓名和合同编号,则可以使用下面的查询,
图 6 42 查询未完成付款的合同
6.4.5. 如何处理合同中的产品信息
一个合同中会订购多个产品,记录的信息有产品的编号、产品的数量和产品的价格。这里为什么要记录产品的价格呢?它不是可以从产品的基本信息实体中查询得到吗?这是因为产品基本信息中的产品价格是不断变化的,合同签订时的产品价格可以从产品信息表中查询,但随着时间的变化,产品信息中的价格就发生了变化,因此,需要合同信息中记录产品当时的销售价格。另外,为了如实反映产品的价格情况,在示例中使用产品的公开价格和折扣两个属性。
与合同的付款信息类似,在示例中使用一个单独的实体“CONTRACT_PRODUCT”存储合同的产品信息。
6.4.6. 如何处理订单信息
在示例中,我们使用了两个实体“ORDER_HEADER”和“ORDER_DETAIL”记录订单信息,分别表示订单概要信息和订单明细。在订单概要信息实体中记录订单的基本信息如订单的日期等,在订单明细中记录订单的产品信息。
可能会有人提出这样的问题,订单的产品不是可以从合同的产品中查询得到吗?假如这样处理,其前提是合同中的产品与订单中的产品是一一对应的。但实际情况并不总是这样,比如,有时合同中的产品是公司已经有的产品(可能是以前购买,也可能是自己生产的等)。因此,示例中的处理方法使得数据模型能够更好的满足实际应用的需求。
6.5. 实验
6.5.1. 实验内容与要求
实验一:售后服务管理系统数据建模
仔细阅读合同管理应用需求的说明(参见第9章),在此基础上使用ERwin Data Modeler数据建模工具创建企业合同管理的数据模型,并将其中的物理模型生成到SQL Server数据库管理系统(注:版本不限),根据完成的内容和过程编写一份数据建模的报告,数据建模的重点放在售后服务部分。需要在报告中将ERwin(也可使用其它数据建模工具)创建的数据模型的ERD放到报告中(可以截图),结合所设计的ERD回答下面问题:
(1) 如何实现售后服务中的产品服务期限的?
(2) 如何记录售后服务的产品信息?
(3) 如何记录技术服务工程师(包括服务专员)的信息?
(4) 一个完整的服务信息(如维修一个磁盘可能包括第一次打电话咨询、维修等由多个小服务组成一个大服务)是如何记录的?
ERrin r9支持SQL Server 2012,其试用版下载地址:
http://rmdmdownloads.ca.com/akdlm/ERwin/EvalCE/ERwin.exe
如果使用ERwin不支持相应版本的SQL Server,需要将生成的SQL语句拷贝到SQL Server的查询分析器去执行。

猜你喜欢

转载自blog.csdn.net/maguanzhan7939/article/details/77924686