数据建模与实现的过程大致可以这样描述:思考 -> 高级设计 -> 关系数据库模式 -> 关系DBMS。如果用PowerDesigner工具,这个过程可以描述为创建CDM->转换为PDM->生成DBMS实现。本节着重介绍高级设计的表示及向关系数据库模式转换的方法。
PowerDesigner工具的使用参见这里:http://www.cnblogs.com/yxonline/category/89658.html
业务建模的一篇介绍参见这里:http://www.cnblogs.com/DBFocus/archive/2011/10/12/2208580.html
最早的方法是ER图,最近的均势是使用UML,不论哪种方式都必须在确定之后方可向模式转化。
4.1 E/R模型
4.1.1 基本概念
E/R图是一种描述数据库模式的符号。
实体:某种抽象的对象,相似实体的集合形成实体集。对于学生表,每个学生是一个实体,学生集合为实体集。
属性:实体拥有的属性,如学生的姓名、性别等。
联系:两个或多个实体集的连接。如学生与教室的占有关系。
实体联系图:用来描述实体集、属性和联系的图示。用矩形表示实体集、椭圆形表示属性、菱形表示联系。
以下图为例介绍E/R图的核心概念
4.1.2 联系的多样性
1:N 关系 如果实体集E中任一实体与实体集F中多个实体存在关系,则称E与F之间存在1对多关系,一个制片厂可以生产多部电影
1:1关系 如果E和F即是1:N,也是N:1关系,则称E和F之间存在1对1关系
M:N关系 实体集E中实体与F中实体可以进行任意多个关联,如一个明星可以出演多个电影,一个电影由多个明星来出演。
以E/R图中用→表示关系的多样性,如果E与F是多到1的关系,则将箭头指向F。如图中一个电影是由一个制片厂生产,无联合制作的情况。对于1:1关系,则在关系的两端均指向对应的实体。值得注意的是箭头表示最多一个,不代表一定存在。
在同一关系中,一个实体可能多次出现。这时需要画两条线,但对每次出现在每条线上标示其角色以示区别。
4.1.3 多重联系
除了二元关联,还有更复杂的多元关联,仍可以由菱形来表示多元关系。而且联系可以有自己的属性,以表示属于此次关联的一些信息。
有一些数据模型要求联系必须是二元的,如UML。E/R不限制联系的重数,但有必要了解如何来做这种转换。定义连接实体集为多路联系元组的实体集。针对原来多路联系的每个实体集,从连接实体引入多对一联系。因为连接实体集扮演了多个角色,每个角色就是一个联系。
4.1.4 E/R模型中的子类
类似面向对象, 一些实体集可能含有公共实体,但其各自又有一些不同的实体,可以把公共实体抽出来作为公共实体集。这里也可以使用isa关系。在图中我们使用三角形来表示。三角形的一边与子类相连,此边相对的角与父类相连。
4.1.5 键的表示
实体集的键与关系的键具有相同的概念,不在经重复。在E/R图中,键的属性用下划线标出。当实体有多个键时,只在主键下划出,没有办法表示多个键。
4.1.6 引用完整性的表示
用圆箭头批向F表示F实体必须存在。
4.1.7 弱实体集
如果实体集E的键是由另一个实体集的部分或全部属性构成。实体集的来源有两种。
第一,E的实体是集合F中实体的一部分,如果只考虑E实体的名字装饰不具有唯一性,需要再考虑其所属的实体的名字才能确定。例如对于电视剧剧集信息E,每部电视剧可能都从第1集到第N集这样的编号,但其他电视剧也有这样的名字。为了唯一命名一个居住信息,就需要同时考虑剧集所属的电视剧的名字及其自己的名字。
第二,上面介绍的连接实体集--作为消除多路联系的方法。这些实体集通常没自己的属性。它们的键由它们所连接的实体的键构成。
用双矩形表示弱实体集,有双菱形表示一个多对一的联系,它有助于提供弱实体集的键。在那些为弱实体集提供键的属性上加下划线。
弱实体集E的键组成为:若干个其自己的属性,从E到其他实体集的多对G 联系连接的键属性。这些多对一联系称为E的支持联系,从E到达的实体集称为支持实体集。
4.2 从E/R图到关系设计
4.2.1 设计原则
忠实性:设计应当忠实于现实中应用的具体要求。例如对于课程和导师两个实体,二者的传授关系可能是N:1或是N:M的形式,这取决于现实中是否允许教这门课的多个导师来进行记录。
避免冗余:每件事只表达一次,冗余会导致异常。
简单性:除非有必要,不要在设计中添加更多的成分。添加的成分理论上虽然正确,但在现实应用中成为多余就会导致复杂性且容易出错。
选择正确的关系:实体集可以用不同的方式联系起来,但必须考虑采用最合适的方式来表达实体间的关系。针对上面图中的制片合同的关系,电影和影星之间是否需要一个额外的联系需要视具体情况而定。如果部分影星没有在合同中但确实需要表示电影中影星的信息,则需要额外的关系:明星出演电影。
选择属性还是实体集/联系:在上面的电影制片厂关系中,我们是否可以把这个关系去掉,而是把制片厂的名称和地址直接作为电影的属性呢?这个问题的答案是否定的,这样做会导致更新和删除异常。然而如果没有地址,把名字写入电影却是合适的。针对这个问题,实体集E在以下的条件下,可以不通过关系关联,而将E的所有属性放入另一个实体中作为属性:
1). 所有与E有关的关系都必须有箭头指向E,即E必须是多对一联系中的一。
2). 如果E有多个属性,则所有属性构成E的唯一键。
3). 没有联系包含E多次。
4.2.2 E.R到关系的转化
对任意的非弱实体集,可创建一个同名且具有相同属性集的关系。
联系转换为同名的关系,添加这个联系的属性,对于R涉及的每一个实体集,将它们的键属性作为关系的一部分加入。
1). 处理 关系组合
对于实体集E和F,为多对一的关系,如果直接转换,则生成两个实体关系,外加一个联系的关系。由于是多对一关系, 在一的关系F上,其键可以确定属性的唯一值,因此三个关系可以合并为两个关系。其中一个关系为F实体转换而成的,另一个关系则包含如下模式:E的所有属性,F的键属性,联系R的任何属性。
例如,对于上面电影和制片厂,电影和关系可以组合为Movie( title , year, length, gnera, studionName),制片厂转换为Studio(studionName, address)
即使是有多条从E到其他实体集的多对一联系时也是如此。这样做可以提高查询的效率。
2) 处理弱实体集
若W是弱实体集,则W转化为关系后的模式组成为:W的所有属性,与W相连的支持联系的所有属性,对每个连接W的支持联系,即从W到E的多对一联系,要包含E的所有键属性。
不需要为与W相连的支持联系构造关系。
例如,对于上面剧集描述与电视剧,转换的关系为SerialDesc( serialNo,serialName desc), Serial(serialName,director)。
3) 处理子类结构
有三种策略可以把一个isa层次实体集转化为关系。
第一,遵照E/R观点。为任一个在层次中的实体集创建一个关系,它包含了的根的键属性和自身的属性。例如针对电影的继承关系可以有如下转换:Movie(title,year,length,genre), Cartoons(title,year,desc)。isa联系不能创建为关系。
第二,把实体看作属于单个类的对象。对于每个子实体,创建一个包含了子树中所有实体集的所有属性的关系。例如针对上面的继承需要转换为两个关系,每个关系均包含各自的所有属性,Movie(title,year,length,genre),MovieCartoons(title,year,length,genre,desc)
第三,使用空值。创建一个包含层次中所有实体集的属性的关系。每个实体由一个元组表示,对于实体没有属性,则设置此元组的相应分量为空。此次我们只需要一个表:Movie(title,year,length,genre,desc),它包含了所有属性。
上面三种方法各自均有优缺点,下面列出主要的几点。
第一,由于涉及多个关系的查询代价昂贵,所以人们更愿意在一个关系中寻找查寻需要的所有属性。空值法在这一点上有很好的性能。
第二,有时候为了避免重复。面向对象方法,每个关系只包含针对自己的属性,占用了尽可能少的空间。在空值法中,大量的空白字段就会浪费较多的空间。
4.3 UML
在UML中将实体和联系都可以表示类之间的关系。在理解了E/R之后,理解UML是比较容易的事情。
键的表示:在类图中为表示键的属性后加PK,表示为主键。
联系的表示:两个类之间的直线即可表示关联,关联的名字写在线的下方。通过在线的两端增加m..n来进行度的声明以及引用关系的声明。如果联系拥有自己的属性,则通过关联类来表示。如果联系有多对一的关系,则可以使用连接上的聚集和组合的属性,则通过在线的端点加菱形来表示。
自关联:如果关联两端连接同一个类,称为自关联。为区分自关联中表现的角色,分别给关联的两端写一个名字。
E/R子类在UML中采用标准的OO表示方法。
4.4 UML图到关系设计
关键点同E/R到关系的转换,不在此重复。