1 / 48

第九章 联系的实现

第九章 联系的实现. 对象类型间通过属性的引用建立了对象实例间的联系 本章重点研究对象间联系的语义及其实现方法 对象间的联系可以是 n 元联系 (n ≥2 ) n 个对象间通过一个联系进行联接 其中最简单,常用的是二元联系 (n=2) 二元联系中,二个对象间的联系语义有 1:1 , 1:N , N:1 , N:M. Rbin. Tright. Tleft. §9.1 没有属性的二元联系. 一个二元联系本身没有任何属性,它只表达了二个对象类型间的联系 联系的实现:通过设置进入点 entry point 来完成

tamra
Download Presentation

第九章 联系的实现

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 第九章 联系的实现 • 对象类型间通过属性的引用建立了对象实例间的联系 • 本章重点研究对象间联系的语义及其实现方法 • 对象间的联系可以是n元联系(n≥2) n个对象间通过一个联系进行联接 • 其中最简单,常用的是二元联系(n=2) • 二元联系中,二个对象间的联系语义有 1:1,1:N,N:1,N:M

  2. Rbin Tright Tleft §9.1 没有属性的二元联系 • 一个二元联系本身没有任何属性,它只表达了二个对象类型间的联系 • 联系的实现:通过设置进入点entry point来完成 • 进入点设在Tleft处:Tleft类型增加一个引用对象Tright的属性,Tright类型无需增加属性 • 进入点设在Tright处 • 增加一个对象类型Rbin,它仅有二个元组属性,分别是Tleft类型和Tright类型,这种方法可以加载Rbin本身独特的属性

  3. 1:1的二元联系的实现 (一)无冗余的表达方式—一个联系仅在一个对象属性中表达 • 采用① (或者②)方法—应当从查询需求入手,选择查询频度高的一方作为进入点 —问题: 1)反向查询速度极慢:对一个特定的Tright实 例,查其相应的Tleft实例时需要查过所有的 Tleft实例集合 2)即使正向查询,若存在联系的偶对集合很 小,那么仍然费时

  4. 1 1 R Tright Tleft • 采用方法③—定义一个Rbin类型,Tr并由系统维护Tr集合,适用于Tr相对Tleft(Tright)较小时 —问题: 1)需要二次查找才能定位 2)当Tr集合仍然庞大是,寻找一组特定的偶对效率仍然很低——需要建立索引 type Tleft is body [… R:Tright; …] end type Tleft; type Tright body [… R-1 :Tleft; …] end type Tright; type TR is with extension is body [left:Tleft; right:Tright;] end type TR;

  5. 1:1的二元联系的实现(续) (二)冗余的表达方式1——二个进入点 • 在Tleft中建立R属性—类型为Tright • 在Tright中建立R-1属性—类型为Tleft 优点:提高反向查询效率 问题:当两个对象实例间的联系发生变更时,容易产生修改异常,生成对象库状态的一致性受到破坏

  6. 解决方法:重新定义R属性的值接受操作 refine R:←Tright code setR; define setR(oright) is begin oright.R-1 := self; self.R := oright; end define setR; • 由此,确保了R属性与.R-1属性的同步修改 • 必须利用封装技术来控制不会单独修改.R-1 (.R-1只读)

  7. 总结 • 利用封装技术重新定义关联属性的状态的修改 • 特别注意不能在同一时间,以同样的方式修改类型Tright的.R-1的值接受操作,否则导致递归操作的无限循环 即: • 重写Tleft,R的值接受操作 • 隐藏Tright,.R-1的值接受操作,使其为只读类型

  8. type Tright body [… R-1 :TR; …] end type Tright; type TR is with extension is body [left:Tleft; right:Tright;] end type TR; type Tleft is body [… R:TR; …] end type Tleft; (三)冗余表达方式2—采用显式的冗余方式 • 用TR作为中间联系方法将二者显式相连 • 查询为二次查询,但管理方便 • 对R, R-1的修改自然要遵照异常处理方式重定义VCO和做相应的隐藏

  9. R Tleft Tright 1:N 的二元 联系的实现 1 N type Tleftis type Trightistype TR body body with extension is […… […… body R: { Tright }; R-1: Tleft; [left: Tleft ; ……] ……] right: Tright;] end type Tleft; end type Tright ; end type TR ; 方式(1) 方式(2) 方式(3)

  10. 其中唯有方式(2)能确保一致性约束,R-是单值的。其中唯有方式(2)能确保一致性约束,R-是单值的。 • 方式(1)(3)均不能确保两对象间1:N的约束。 • 对(1),必须重新定义R属性的值接受操作 • 对(3),必须对TR的对象实例库进行一致性维护,即TR的insert操作进行一致性维护

  11. R Tleft Tright N:M的二元联系的实现 N M type Tleftistype Trightistype TR body body with extension is […… […… body R: {Tright }; R-1:{ Tleft }; [left: Tleft ; ……] ……] right: Tright;] end type Tleft; end type Tright;; end type TR; 方式(1) 方式(2) 方式(3) • 采用原则:以最大查询频率为依据选择入口点 • 可以采用组合冗余方法,但需要进行状态一致性维护

  12. 具有K个属性的二元联系的实现 ak a1 … • 1:1的联系:仍然可以采用方式(1)或(2),K个属性寄放在Tleft或Tright • 1:N的联系—只能放在单值属性的对象类型方 • N:M的联系—寄存在那一方均不合适,只能采用方式(3),定义此属性的类型TR, TR具有K+2个元组属性 Tright Tleft R

  13. Type TR withextension is Body [left: Tleft ; right: Tright; a1:T1R; … ak:TkR;] operations declare TR: Tleft , Tright,T1R, …, TkR -> TR code initTR; implementation define initTR(Oleft ,Oright,O1,…,Ok) is begin self.left := Oleft; self.right := Oright; self.a1 := O1; …; self.ak := Ok ; enddefine initTR endtype TR

  14. N—元联系的实现 • 只能采用方式(3)—建立TR类型处理 • 对初始化进行重定义,以保证约束的一致性。 • 为了检索高效率,需要考虑受控的冗余建模。 ak a1 … T1 Tn T2 R

  15. type TR withextensionis Body [entitiy1: T1 ; … entitiyn: Tn; a1:T1R; … ak:TkR;] operations declare TR: T1 ,… , Tn,T1R, …, TkR -> TR … implementation … endtype TR

  16. residesIn Engineers Offices 示例分析(一) • 1-1联系实例:工程师与他所占办公室的联系处理 约束条件:一个工程师一间办公室 type Engineer istype Office is bodybody […… […… resideIn: Office; isOccupied: Engineer; ……] ……] endtype Engineer ; endtype Office; 先有工程师,再分 经常查询某办公室的工程师是谁 配房间 1 1

  17. 用方式(1)和(2)组合建模下冗余的一致性维护 • 联系更新时一般的方式 (1)If (thePenthouse.isOccupiedby != NULL) thePenthouse.isOccupiedby.residesIn :=NULL; (2)If (leonardo.residesIn != NULL ) leonardo.residesIn. isOccupiedby :=NULL; (3) leonardo.residesIn := thePenthouse; (4) thePenthouseis.Occupiedby := leonardo;

  18. 设计操作moveToOffice来维护一致性状态 define moveToOffice(newResidence ) is begin if (newResidence.isOccupiedBy != NULL) newResidence.isOccupiedBy.residesIn := NULL; if (self.residesIn != NULL ) self.residesIn.isOccupiedBy := NULL; self.residesIn := newResidence; newResidence. isOccupiedBy := self; enddefine moveToOffice;

  19. worksFor Engineers Divisions 示例分析(二) • 工程师与部门间的1:N的联系 type Engineer istype Division is bodybody […… […… worksfor: Division; employs: EngineerSet; ……] ……] endtype Engineer ; endtype Division; type EngineerSet is body {Engineer} endtype EngineerSet; N 1

  20. 控制类型冗余模型的两个操作 • hire define hire(newEng) is Begin self.employs.insert(newEng); newEng.worksFor := self; enddefine hire; • Fire define fire(badEng) is Begin self.employs.remove(badEng); badEng.worksFor := NULL; end define hire; • 聘用和辞退两个操作可以保持DB的完整性约束。

  21. Sub N products composition 1 Super 递归的1:N的关系 • 产品与产品间具有递归的组合联系 • E-R图的展开可以有两种描述模式

  22. A:通过Super属性—表达了is.part-of的语义关系: 即:一个产品属于上层产品的一个部件 type Product is body […… super: Product ; ……] endtype Product ; 适用范围:查找某种产品被组装在什么部件中。沿part-of路径进行导航或访问 Super: Super: Super: Super: Super: Super: Super: Super:

  23. B:通过Sub属性—表达了partlist的语义关系: 即:一个部件由几个子部件所组成 type Product is body […… sub: ProductSet ; ……] endtype Product ; type ProductSet is body{ Product } end type ProductSet ; 适用范围:查找组成某部件的所有子部件 Sub:{} Sub:{} Sub:{} Sub:{} Sub:{} Sub:{} Sub:{} Sub:{}

  24. 应用示例 • 操作partlist:输出组成某个产品的所有部件 • 采用结构I define partList is var resultSet: ProductSet; begin resultSet.create; !!create an empty set resultSet.insert( self ); foreach ( part inext( Product )) if ( part.super = self ) resultSet.setUnion(part.partList); !!recursive call of partList return resultSet end define partList

  25. 采用结构II define partList is var resultSet: ProductSet; begin resultSet.create; resultSet.insert( self ); foreach (part inself.sub) resultSet.setUnion(part.partList); !!recursive call of partList return resultSet; end define partList; • 该程序是高效的。

  26. 操作is part of: • 采用结构I define isPartOf(theSuperPart) is !!is self a subpart of theSuperPart? var part: Product Begin part := self; while ( part != NULL ) If ( part = theSuperPart ) return true; else part := part.super; return false; end define isPartOf; • 高效,只需沿self向上查找到根一条路径

  27. 采用结构II define isPartOf(theSuperPart) is var isUsed: bool := false; Begin foreach ( part in theSuperPart.partList) If ( part = self ) isUsed := true; !!we could already exit the loop here return isUsed; end define isPartOf; • 低效,需到theSuperPart节点的所有组件中寻找self

  28. 第III种冗余组合模式 type product is body [… super:Product; sub:ProductSet; … ] end type product • 该模式的使用中,重要的是维护DB的一致性

  29. designs Engineers Products N:M关系举例 N M • 方式一,采用组合的冗余表达方式 type Engineer istype Product is body body […… […… designs: ProductSet; designedBy: EngineerSet; ……] ……] end type Engineer ; end type Product; type EngineerSet istype ProductSet is body {Engineer} body {Product} end type EngineerSet; end type ProductSet;

  30. 方式二,采用单独定义的TR类型表示联系 type Designs with extension is body [theParticipatingEngineer:Engineer; theProduct:Product] end type Designs

  31. 互逆联系的实现 • 问题的提出:在用冗余表达对象间的联系时,如何用系统来自动维护修改的一致性? • 互逆联系:对称的联系偶对,由inverse显示标识。 • 系统将按照用户标识指定的互逆联系的修改进行自动的一致性维护。

  32. (一)1:1的单值逆属性 • 示例:关于婚姻的一致性控制,没有两个类型及其冗余的联系: type Man is type Woman is body body [ [ … … wife:Woman husband:Man ... … ]; ]; end type Man; end type Woman

  33. mickeyMouse.wife := miniMouse; miniMouse.husbnd:=donaldDuck; • 控制婚姻联系的一致性约束条件为: w.husband =m; 当且仅当 m.wife = w • 如果上面的约束由系统自动维护,则需要用户显示的指明互逆联系

  34. type Man is … wife : Woman inverse Woman$husband; … end type Man; type Woman is … husband : Man inverse Man$wife; … end type Woman; mickeyMouse.wife := miniMouse; miniMouse.husband:=donaldDuck;

  35. (二)多值逆属性 • 利用多值(集合)逆属性来实现对象间1:N联系的冗余表示,例如递归组合属性super与sub(多值)间的互逆的联系。 • 示例:用户界面窗口的设计——(无重叠的全包含窗口) — 窗口:用一个矩形框表示 —窗口之间是全包含的联系

  36. r1 r11 其中: • r1包含r11、r12 且r11<r1 • r1不直接包含 r111, r111被r11直接包含 r111 r12 r112

  37. type Rectangle is body [ height,length:float; contains:{Rectangle} ]; … end type Rectangle; 其中联系属性contains是一个多值集合属性,其元素为矩形框对象。

  38. 现定义contains的一个逆关系containsIn,其约束为:现定义contains的一个逆关系containsIn,其约束为: 若两个窗口对象r,r’具有r contains r’,则 r’ containsIn r, 即 containsIn(r’)={r| r’∈contains(r)} 最多仅由一个矩形r直接包含r’。 r111 r11 r112 r1 r12

  39. 包含一对互逆联系属性的窗口类型定义如下: type Rectangle is body [ height,length:float; contains:{Rectangle} inverse Rectangle$containedIn; containedIn:Rectangle inverse Rectangle$contains; ]; … end type Rectangle;

  40. §9.6 复合对象引用的支持 • GOM支持对象间引用的更复杂的语义描述 • 引用的分类 — 弱引用: (weak reference)两个对象o1,o2除了它们之间存在一个引用联系外,没有任何其它的语义约束,即它们在同一个语义层次上是独立的两个实体,则称o1,o2间是一个弱引用 — 复合对象引用:(composite reference) 复合对象对部分对象的引用具有复杂的语义约束。

  41. 复合对象引用的语义分类 • 依赖/独立 Dependent/Independent • 专有/共享 Exclusive/Shared • 它们组合成了四种复合对象的引用语义

  42. 依赖—专有复合对象引用(最严格的语义引用) • 语义表示:该引用保证部分对象仅仅可能是一个复合对象的成份 • 一致性约束:部分对象当且仅当它所依赖的一个复合对象存在时才存在, • 约束的实现— 复合对象与部分对象的删除要捆绑进行 • 示例:

  43. 1. type computer is body [ cpu: dependent exclusive processor; … ]; end type computer; 说明:⑴cpu芯片与某主板共存亡,不被共享 ⑵不排除处理器主板上还可以有其他器件,如内存片则不是依赖主板的器件 2. 大楼与大楼内房间的关系

  44. 独立— 专有复合对象引用 • 语义表示:部分对象仅与一个复合对象关联,但它有自己的独立性 • 一致性约束:部分对象不允许共享;当主对象删除时,部分对象允许在对象库中独立存在 • 例:

  45. type Automobile is body [ engine : independent exclusive Motor ; … ]; end type Automobile; 说明:⑴汽车引擎只为一台汽车所专用 ⑵引擎可以被复用(由一台汽车转到另一台)

  46. 依赖— 共享复合对象的引用 • 语义表示:部分对象可以共享,但它仍然是依赖于被关联的复合对象的存在而存在 • 一致性约束:部分对象的删除取决于所有引用它的复合对象的删除 • 示例:

  47. 1. type Document is body [ chapter : dependent shared Chapter; … ]; end type Document; 说明:文档的“章”可以共享,但当所有引用它的章被删除时,“章”的内容也自然不再存在 2. 客户档案依赖合同而存在 — 依赖 一个客户可以签多份合同 — 共享 当所有合同到期后,该客户也就不再出现

  48. 独立— 共享复合对象的引用 • 语义表示:部分对象即是共享的也是独立的(约束最弱) • 示例:发动机设计图— 共享的部分对象可以用在不同的汽车设计中;当汽车型号更新换代了,发动机设计仍然需要保存 type CarDesign is body [ engineDesign : independent shared MotorDesihn; ...] end type CarDesign;

More Related