第三周翻译(《Database.System.Concepts》7.7 Entity-Relationship Design Issues)

Tip:参考前人翻译

实体——联系设计问题

  针对实体集和联系集的概念并不明确的现象,并且定义一组实体和它们的相互联系可能会有许多不同的方式。本节我们讨论E-R数据库模式设计中的一些基本问题。设计过程将在7..10节更详细地讨论。

7.7.1 用实体集还是用属性

  考虑到具有新增属性phone_number的实体集instructor(如图7-17a)。很容易就会把电话作为一个单独的实体,具有属性phone_number和location;而地点可能是电话所处于的办公室或者家中,所以移动电话就可以用“移动”来备注。但如果我们采用这样的观点,那么我们就不给instructor增加属性phone_number,相反的,我们可以创建:

   实体集phone,具有属性phone_number和location。

   联系集inst_phone,表示老师和他们拥有的电话之间的关系。

   这种方法如图7-17b。

 

 

   那么,老师的两个定义之间又有什么主要差别?把电话看成一个属性,phone_number表示每个老师刚好有一个电话号码与他相关。而如果把电话当成一个实体phone,允许每个老师可以有若干个电话号码(包括零)和他相关联。同样的,也可以简便地将phone_number定义为有多个值的属性,从而允许每个老师有多个电话。

  而两种方法的主要区别在于,当一个人可能希望保存关于电话的其他信息时,如电话的位置,或者类型(移动电话、视频电话或者普通的老式电话),或者想共享该电话的所有成员时,把电话当成一个实体是一种比较好的建模方法。所以,把电话看成一个实体比把它当成一个属性的方式更具有通用性;而当通用的这种方法更为有效时,这种定义形式就更加合适了。


  相反的,把(一位老师的)name属性看做一个实体就不是很合适,把name作为一个实体,本身就不具有说服力(和电话的情况相反)。所以,合适的做法就是把name当成instructor实体集的一个属性。

  从上述的这个例子就提出两个问题:由什么构成了属性?而又是什么构成了实体集?令人遗憾的是,关于这两个问题并不是那么简单就能回答的。因为区别它们主要依靠于被建模的实际的企业的结构,和被商议的属性的相关定义。

  一个常见的错误就是错用一个实体集的主键作为另一个实体集的属性,而不是用联系。例如,虽然每位老师只能指导一名学生,但将student的ID当成instructor的属性也是不正确的,而用advisor联系代表学生和老师之间的关系才是正确的方法,因为这样可以更准确地表示出两者之间的联系而不是简单将这种关系隐藏在属性中。

  人们经常犯的与此相关的另外一个错误是把相关实体集的主键属性当成联系集的属性。例如,ID(student的主键属性)和ID(instructor的主键)不能在advisor联系中作为属性出现,因为在联系集中就已经包含了这些主键的属性,所以这样的做法是不对的。

7.7.2 用实体集还是用联系集

  一个对象最好被表示为实体集还是联系集并不总是显而易见的。如图7-15所示,我们用takes联系集对学生选择课程(某一次开课)建模。另一种方式是想象对于每一个学生选的每门课程有一个课程-注册记录。那么,我们用一个叫registration的实体集代表课程-注册记录。每个registration实体恰好与一个学生和一次开课相关联,所以,我们就会有两个联系集,一个将课程-注册记录和学生相关联,另一个把课程-注册记录和课程关联。如图7-18所示,我们将图7-15中section和student实体集之间的takes联系集用一个实体集和两个联系集替代:

  Registration,代表课程-注册记录的实体集。

  Section_reg,关联registration和course的联系集。

  Student_reg,关联registration和 student的联系集。

注意,我们使用双线表示registration实体全部参与。

 

图7-15和图7-18的方法都准确地表达了大学的信息,但是使用takes的方法更紧凑也更可取。然而,如果注册办公室通过课程—注册记录与其他信息相关联,那么最好还是让它本身作为一个实体。

  在决定用实体集还是联系集时可采用的一个原则就是,当描述发生在实体间的行为时采用联系集。这一方法在决定是否将某些属性表示为联系可能会更合适时,很有用。

  而我们以后会看到,当从E-R模式中创建关系模式时,这些属性可能会出现在从advisor联系集创建出的模式中,但是,它们并不应该出现在advisor联系集中。

7.7.3 二元还是n元联系集

  数据库中的联系通常都是二元的情况,但在一些看来非二元的联系实际上可以用多个二元联系更好地表示。例如,可以创建一个三元联系parent,将一个孩子和他/她的母亲和父亲相关联。然而,这一联系也可以用两个二元联系分别来表示,即mother和father,分别将孩子与他/她的母亲和父亲相关联。使用mother和father两个联系使我们可以记录孩子的母亲,即使我们不知道父亲是谁,而对于这种情况三元联系parent中必然会有一个空值。所以在这个例子中用二元联系更好。

  实际上,一个非二元的(n元,n>2)联系集总可以用一组不同的二元联系集来替代。简单起见,考虑一个抽象的三元(n=3)联系集R,它将实体集A、B和C联系起来。用实体集E替代联系集R,并创建三个联系集,如图7-19所示;

  Ra,关联E和A。

  Rb,关联E和B。

  Rc,关联 E和C。

  而如果联系集R有属性,那么将这些属性赋给实体集E:进一步,为E创建一个特殊的标识属性(因为它必须能够通过其属性值来区别实体集中的各个实体)。针对联系集R中的每个联系(ai,bi,ci),在实体集E中创建一个新的实体ei。然后,在三个新联系集中,分别插入新联系如下;

  在Ra中插入(ei,ai)。

  在Rb中插入(ei,bi)。

  在Rc中插入(ei,ci)。


  那么就可以将这一过程直接推广到n元联系集的情况。因此,在概念上可以限制E-R模型只包含二元联系集。然而,这种限制情况并不总是令人满意的。

  对于为表示联系集而间接创建的实体集,我们可能会为其创建一个标识属性。该标识属性和额外所需的那些联系集增加了设计的复杂程度以及对总的存储空间的需求(我们将在7.6节看到这一点)。

  N元联系集可以更清晰地表示几个实体集参与单个联系集。

  但有可能无法将三元联系上的约束转变为二元联系上的约束。例如,考虑一个约束,表明R是从A、B到C多对一的;也就是,来自A和B的每一对实体最多与一个C实体关联。这种约束就不能用联系集Ra,Rb和Rc上的基数约束来表示。

  考虑7.2.2节中的联系集proj_guide,它关联instructor、student和project。不能直接将proj_guide拆分为instructor和project之间的二元联系和student和project之间的二元联系。如果这么做,可以记录老师Kate同学生Shankar和Zhang一起参与项目A和B;但是无法记录Katz同Shankar一起参与项目A并且同Zhang一起参与项目B,而不是同Zhang一起参与项目A或者同Shangkar一起参与项目B。


  联系集proj_guide 可以通过创建一个如上所述的新实体集来拆分为二元联系。但是,这么做却不是很自然。

7.7.4 联系属性的布局

  一个联系的映射基数比率会影响联系属性的布局。因此,一对一或一对多联系集的属性可以放到一个参与该联系的实体集中,而不是放到联系集中。例如,我们指明advisor是一个一对多的联系集,也就是一个老师可以指导多个学生,但每个学生只能有一个导师。在这种情况下,表示老师何时成为学生导师的属性date可以与student实体集相关联,如图7-20所示。(为了保持图例简单,只显示了两个实体集的部分属性)。由于每个student实体最多和一个instructor实例相联系。因此将属性date放在student实体集中和将属性date放在advisor联系集中具有相同的含义。一对多联系集的属性只能重置到参与联系的“多”方的实体集中。而对于一对一的联系集,联系的属性可以放到任意一个参与联系的实体中。

  设计时把描述性属性作为联系集的属性还是实体集的属性这一决定,应该反映出被建模对象的特点。设计者可以选择保留date作为advisor的属性,以直观地表明指导关系的日期,而不是学生校内状态的其他一些方面(例如,被大学录取的日期)。

  属性位置的选择在多对多联系集中体现得更加清楚。回到刚才的例子,让我们指出可能更符合实际的情况,定义advisor为一个多对多联系集,表明一个老师可以指导一个或多个学生,而一个学生可以被一个或者多个教师辅导。而如果想要表示一个特定的老师成为一个特定学生的导师的日期,date则必须作为联系集advisor的属性,而不是任何一个参与的实体集的属性。例如,如果把date作为student的属性,则我们无法知道哪个教师在该特定日期成为他的导师。当一个属性是由参与的实体集联合确定而不是由单独的某个实体集确定时,该属性就必须放到多对多联系集中。图7-3给出了作为联系属性的date的位置。而为了图例的简单,只显示了两个实体集的部分属性。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值