1 / 53

第十四章 关联对象访问 Associative Object Access

第十四章 关联对象访问 Associative Object Access. 本章重点讲述 GOM 对关联对象查询的支持,即如何实现一个查询和如何描述用户的查询要求 在 O-O DBMS 中,实现一个查询是通过多态的 Select 函数来实现的 GOM 支持二种查询语言 GOMql 、 GOMsql 其中 GOMql 是基于关系语言 QUEL 在面向对象上的扩展 GOMsql 是 SQL 在面向对象上的扩展 关联查询的操作对象为:类型范围 (Type Extention) ,用户定义的集合对象和表对象. 多态的关联选择操作定义及其实现.

wayne
Télécharger la présentation

第十四章 关联对象访问 Associative Object Access

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. 第十四章 关联对象访问Associative Object Access • 本章重点讲述GOM对关联对象查询的支持,即如何实现一个查询和如何描述用户的查询要求 • 在O-O DBMS中,实现一个查询是通过多态的Select函数来实现的 • GOM支持二种查询语言GOMql、GOMsql • 其中GOMql是基于关系语言QUEL在面向对象上的扩展 • GOMsql是SQL在面向对象上的扩展 • 关联查询的操作对象为:类型范围(Type Extention),用户定义的集合对象和表对象

  2. 多态的关联选择操作定义及其实现 • 关联选择操作需要一个操作对象说明—在某个对象实例集合上,需要一个条件表达式作为选择的依据—选择谓词 • 当定义一个多态的选择操作时,选择谓词将以函数变元的方式作为操作变元 • 当选择谓词本身需要参数时,该参数必须在选择操作的参数表中说明 • 多态的选择操作的共同名字为Select

  3. 无参数的选择谓词—简单的布尔函数 • 多态选择操作说明为 Polymorph overload select (\t1<={\t2}) :\t1 || ( \t2 || -> bool ) -> \t1 Code selectNoParam • 语义为 • 类型\t1,是一个集合类型,其元素类型为\t2 • Select操作有两个变元:接受者类型为\t1,另一个变元是一个布尔函数,它对类型为\t2的对象进行选择,返回一个布尔型结果 • Select语义对t1的元素用布尔函数进行筛选;

  4. 多态选择操作的实现 define selectNoParam(selPred) is var result: \t1; candidate: \t2; begin result.create; !! 生成空结果集 foreach (candidate in self) if candidate.selPred then result.insert(candidate); return result; end define selectNoParam

  5. 应用举例 • 在立方体实例库中,查找某一个顶点是原点的立方体 • 分析:其选择谓词需要顺次检查一个立方体的8个点,是否有一个点的x、y、z坐标值为0,0±ε —— inOrigin 操作 • 其结果应当是下面二个集合的交集: • 包含在立方体实例集合中的实例——myCuboid所引用 • 满足谓词inOrigin 的实例 • 多态的Select操作可以应用于任何一个集合类型

  6. inOrigin定义 declare inOrigin: Cuboid || bool; define inOrigin is !!判断任何一个顶点是否处于坐标原点 return (( self.v1.x=0.0 ±ε and self.v1.y=0.0 ±ε and self.v1.z=0.0 ±ε)OR … ( self.v8.x=0.0 ±ε and self.v8.y=0.0 ±ε and self.v8.z=0.0 ±ε)); • 变量定义和引用 var myCuboids, theCuboidsInOrigin:CuboidSet; …… theCuboidsInOrigin:=myCuboids.select(inOrigin);

  7. 示例2——查询退休职员 declare isRetired: Employee ||  bool; var retiredEmps: EmployeeSet; … retiredEmps:=ext(Employee).select(isRetired);

  8. 示例3——无名的选择谓词的使用 • 当布尔选择谓词比较简单,则可以λ 符号来实现操作过程的传递 • 示例:选择红色苹果的选择操作 Ⅰ.选择谓词用命名isRed表达 declare isRed: Apple ||bool; define isRed is … Ⅱ.选择谓词用λ表达——直接传递过程 redApples:=myApples.select (λ x: x.color = “red”) GoldCuboid=mycuboid.select (λ x: x.met.name = “gold”)

  9. 带参数的选择谓词 • 该参数是为选择谓词服务的,所以需要在谓词函数中说明 • 由于在引用时,显然需要由Select来引用,因此,在Select的参数表中也要说明,规则如下: poly overload select (\t1<={\t2}):\t1||(\t2||\t3 -> bool), \t3 -> \t1 • 语义:其中类型\t3可以是任何类型,它的约束条件是Select的第三个参数类型\t3,必须与选择谓词所需一个参数类型一致

  10. Select的重载 • Select函数不但是多态的,而且是重载的,它可以根据选择谓词的需要,设定多个参数 • 编译器根据重载规则,从参数的个数,寻找到正确的实现版本 • 其约束条件为:在哑、实结合时,Select的参数个数和各自类型必须与选择谓词的参数个数、类型完全一致

  11. 示例1——一个参数的选择谓词 • 对Cuboid定义一个选择谓词bigCuboid,它能选择体积大于某个阈值的立方体对象 • 定义 declare bigCuboid: Cuboid || float -> bool code bigCuboidCode; define bigCuboidCode(threshold) is return(self.volume > threshold); • 引用 var myCuboids, myBigCuboids: CuboidSet; …… myBigCuboids:= myCuboids.select(bigCuboid, 200.0);

  12. 示例2——二个参数的选择谓词 • 选择体积在一个范围(上限high,下限为low)的立方体 declare volumeRange: Cuboid || float, float -> bool; define volumeRange(low, high) is return (self.volume<=high and self.volume >=low);

  13. 迭代Iterators • 可以在筛选的基础上利用循环进行各种进一步的操作 • 例如:求符合体积要求的Cylinders的体积累加值 declare bigCyl: Cylinder || float -> bool code bigCylCode; define bigCylCode(threshold) return(self.volume>= threshold); …… var c: Cylinder; myCylinders: CylinderSet; bigCylindersTotalWeight: float:=0.0; …… foreach (c in myCylinders.select(bigCyl, 20.0)) bigCylindersTotalWeight:=bigCylindersTotalWeight + c.weight;

  14. 说明性查询语言GOMql • 多态选择函数只是一个关联查询实现的基础,对于复杂的嵌套查询及其优化,表达力度不够,需要通过定义相关的查询语言来实现 • 查询优化有两个方面解决 • 关系代数的优化:编译时进行 • 物理查询路径的优化:执行时进行 • 下面的内容从用户角度出发,如何查询需求正确地用相应的查询语言序列来表达 • GOMql是基于QUEL的扩展

  15. 一个对象实例库 • 类型定义 Type Emp is • {name:string ; • working:Dept; • salary:int;} • type Dept is • {name:string; • mgr:Manager; • profit:int;}; Type Manager • Supertype Emp is • [cars:{Car};]; • type Car is • [license:string; • make:string; • horsepower:int;];

  16. worksIn ------------ mgr ----- cars ----> make -- Emp Dept Manager Car string 1 N N 1 M 1 Dept EMP Manager mgr workIn cars Dept Manager Car • 路径表达式为查找引用链的引用序列 示例: P≡Emp.worksIn.mgr.cars.make • 示例的类型定义中,关联对象的联接,仅仅采用一个进入点的方式

  17. GOMql表达式 • 单目标查询表达式 rang r1:s1,…,rm:sm retrieve ri where p(r1,…, rm) • 多目标查询表达式 rang r1:s1,…,rm:sm retrieve a1:r1,…,aj:rj where p(r1,…, rm) • Range子句:范围说明子句 其中:rj(1≤j≤m)为范围变量表达式,它用于range子句中

  18. 其中,sj(1≤j≤m)必须是下列情况之一 • Sj是一个类型扩展EXT(用类型名表达) • 一个集合对象变量 • 一个列表对象变量 • 一个包含有集合结构的对象变量 • 一个包含有表结构的对象变量 • 一个计算一个集合结构对象的表达式 • 一个计算一个表结构对象的表达式 总之,变量rj被约束到一个相应的聚集类型sj的元素类型

  19. retrieve子句 查询说明子句 • 简单形式:只有一个范围变量——单目标查询 • 复杂形式:通过投影到多个范围变量,构造的多元组——多目标查询 • 实现方法:对目标的范围变量与相应的对象分别进行捆绑,并进行选择谓词查询 • Where子句:选择谓词中,P的变元(r1…rm)∈(s1xs2…xsm)(m个联接) 当目标rj(或者多目标r1…rj)与某一对象捆绑,使P (r1…rj)为真,则该对象被选中

  20. GOMql查询示例(一) • 简单选择谓词示例 查询所有工资超过100000的Emps range e:Emp retrieve e where e.salary>100000.0 查询结果为{id3,id4,id8,id9,id10} • 上述查询需要输出姓名,则为: range e:Emp retrieve e.name where e.salary>100000.0 name “LeMond” “Hinault” “Boss”

  21. GOMql查询示例(二) • 问题:找出其经理为驾驶Jaguar汽车的Emps • 该查询的路径表达式为: p=Emp.workIn.mgr.cars.make = “Jaguar” • 查询表达式为: range e:Emp retrieve e where “Jaguar” in e.worksIn.mgr.cars.make

  22. 系统检测范围变量e的每个捆绑的对象,通过路径可以达到的串值是否为给定的“Jaguar”,若是,则该对象被选中系统检测范围变量e的每个捆绑的对象,通过路径可以达到的串值是否为给定的“Jaguar”,若是,则该对象被选中 • 该选择查询代价巨大,它需要进行如下多个联接: Emp x Dept x Manager x Car • 选择结果为{id1,id2,id8}

  23. 更复杂的查询(一) • 例3:找出选择的经理:他的部门亏损,但仍支付给至少一个雇员工资超过二十万元 range e:Emp,m:Manager retrieve m where m=e.workIn.mgr and e.salary>200000.0 and e.workIn.profit<0.0 • 这里,m=e.worksIn.mgr称为功能联接(对象的“相等”操作子隐含地表示为“标识”)

  24. 例3的优化处理 • 如果在Dept类型中增加一个关联属性{Emp},则例3可以表示为: range d:Dept,m:Manager retrieve m where m=d.mgr and d.profit<0.0 and d.Emp.salary>200000.0

  25. 更复杂的查询(二) • 例4:查找这样的经理:他驾驶过贵重的汽车,而他管理的部门获利很低 range d:Dept,m:Manager,c:Car retrieve m where m=d.mgr and d.profit<100000.0 and c in m.cars and (c.horsepower>150 or c.make=“Jaguar”)

  26. 量词的使用(一) • (一)全称量词表达式 for all rj in sj p 语义为:若集合sj中所有成员rj均满足选择谓词p(rj),则表达式为真,否则为假 示例:查询其经理只开宝马车的雇员 range e: Emps,c: Char retrieve e where forall c in e.worksIn.mgr.cars (c.make=”BMW”)

  27. 量词的使用(二) • (二)存在量词表达式 EXIST rj IN sj P(rj) 语义为:若在集合S中至少有一个成员rj满足P(rj) ,则表达式为真,否则为假 示例:查询其经理所用额轿车中有一辆为美洲虎的雇员 range e: Emps,c: Car retrieve e where exists c in e.worksIn.mgr.cars (c.make=”Jaguar”)

  28. 嵌套查询 • 在任何一个集合可以出现的地方,都可以使用range-retrive-where表达式,因此,Gomql允许表达式嵌套 • 表达式嵌套可以发生在三个子句的任何一个中,因为三个子句本身均要求一个集合表达式 • 示例:查询那些只驾驶美洲虎牌或宝马牌,或马力>200的汽车经理

  29. range m: Manager , c: Car retrieve m where forall c in m.cars (c in (range v: Car retrieve v where v.horsePower>200 or v.make=”Jaguar” or v.make=”BMW”))

  30. 查询表达式中聚集函数和类型操作的使用 • 关系查询语言QUEL仅提供少量的聚集函数如count,sum,min,max,avg等 • Gomql允许类型操作作为函数使用。其约束条件为:类型操作不会改变对象的状态,且应当返回一个值 • 函数的范围:在where子句和retrieve子句中都可以使用 • 由于类型操作含有子类型的继承,因此,在执行时,每个对象实例仍然需要动态捆绑相应精化的操作

  31. 示例 • 示例1:查许体积大于150.0的圆柱体 range c: Cylinder retrieve c where c.volume>150.0 • 示例2:查询所有金子做的几何体的总重量 range g: GeometricPrimitive retrieve sum(g.weight) where g.mat.name=”Gold”

  32. 基于SQL的对象查询语言GOMsql • GOMsql是O2SQL的一个子集,它是针对Gom的ODL设计的查询语言 • GOMsql的目标是向用户以供基于SQL的声明和面向集合的查询接口 • 面向对象的基于SQL的查询语言强调的是对象类型,而对象-关系的SQL扩展(SQL-99)强调的仍然是关系,即如何通过关系模型的扩展将对象和类引入 • 其他的面向对象的查询语言--OQL。它是针对ODL设计的查询语言,而ODL是IDL(接口描述语言)--CORBA的一个组件的扩展。 *CORBA是分布式面向对象的计算的一种标准

  33. 示例数据库--边界标识的几何体数据库 type BRep with extension is body [name: string; weight: float; faces: FaceSet;]; … end type BRep; type FaceSet is body {Face} … end type FaceSet; type EdgeSet is body {Edge} … end type EdgeSet; 查找引用链 type Face is body [surface: float; edegs: EdgeSet;]; … end type Face; type VertexSet is body {Vertex} … end type VertexSet; type Edge is body [length: float; vertices: VertexSet;]; … end type Edge; type Vertex is body [x,y,z: float;]; … end type Vertex;

  34. GOMsql的基本查询结构 • GOMsql的基本结构为:select-from-where--记为SFW表达式 • 示例 • selectb.weight from bin BRep whereb.name = “cubo#5” • 在Select子句中,可以引入类型操作函数 • 在from子句中,给出了一个显式定义的范围变量b,b属于BRep类型的对象实例集 • 在where子句中,b的名字要等于cubo#5

  35. 与GOMsql等价的SQL查询表达式 (1) select weight from BRep where name = “cubo#5” (2) selectb.weight from BRep as b whereb.name = “cubo#5” • 范围变量在SQL中被称为别名(aliases) • 方式(1)没有显式的范围变量 • 方式(2)通过别名,定义了一个显式的范围变量b

  36. GOMsql与SQL的主要区别 • SQL:From子句中范围变量必须约束到一个已存在的,旦已被命名的元组赋值的对象集合上,即捆绑到一个关系或一个已建立的 视图上 • 结论:SQL的From子句中不允许嵌套SFW的结构 • GOMsql:From子句中的范围变量可以定义在任何的对象集合上。即无论是持久的命名集合,还是一个临时建立的对象集合,即允许捆绑到另一个SFW表达式上。 • 结论:GOMsql的From子句支持SFW结构的嵌套 • ∆范围变量在From子句中必须显式说明

  37. 范围变量的形式化定义 • GOMsql中,范围变量被捆绑到From子句中的对象集合上 • 形式化描述为: • <form-clause>:: from<rangeVar>in<objectCollection> {,<rangeVar> in < objectCollection >} • < objectCollection >::=(<SFW>)|<Set>|<List>

  38. 嵌套查询表达式 • 示例:查找重量大于1000的几何体中表面积大于10的表面集合。 • 方法:先查找重量大于1000的几何体,再从中挑出表面积大于10的子集 • Select f Form f in (select b.faces from b in Brep where b.weight>1000) where f.surface>10

  39. Brep Face • 这里,外层范围变量f被限定在内部的SFW表达式所返回的Face对象集合上。 • 需要注意的约束条件是:保证范围变量必须有一个唯一的类型,这个类型可以在编译时推导出来 • 一个嵌套查询表达了查询的路径表达式是 faces • 更广泛地,一个范围变量不仅被限定在通过路径表达式检索的对象集合上,而且可以捆绑在任何一个集合上。

  40. 示例2 • 查询重量在100-1000之间的几何体 • 笨办法:先找出重量大于100的几何体,再从中挑出小于1000的来 • select b2.name form b2 in (select b1 from b1 in Brep where b1.weight>100) where b2.weight<1000 • 优化的结果 • select b.name form b in Brep where b.weight<1000 and b.weight>100

  41. 范围变量可以限定到实例集合的属性域上 • 示例:查询立方体cubo#5的8个顶点坐标。 select v.x, v.y, v.z from v in ( select e.vertices from e in ( select f.edges from f in ( select b.faces from b in BRep where b.name="cubo#5" ) ) )

  42. 从最内层的SFW开始(7-9句):b被限定在BRep的类型扩展上从最内层的SFW开始(7-9句):b被限定在BRep的类型扩展上 • 谓词b.name=Cubo#5将b限定到满足谓词的BRep的一个子集上,返回每个几何体的6个面f1-f6。 • 5-6行的SFW接受由内层返回的6个面,并计算它们的边的并集: 产生12个不同的edge对象 • 语句3-4产生24个点的并集--为8个不同的点 • 语句1-2产生8个点x.y.z值

  43. 嵌套查询和路径表达式 • 如下抽象的类型模式 • type T0 is … type Tn-1 is type Tn is body body body [… ; [… ; […] A1: {T1}; An: {Tn}; … …] ; …] ; end type Tn … … end type T0 end type Tn-1 • 即元组类型Ti通过它的属性Ai+1产生对类型Ti的引用

  44. 一个嵌套查询的SFW表达式 • 假如从引用链的始端T0开始,到Tn终止,查询一个原子类型SomeAttr的值,那么它的查询如下: • select an.someAttr from anin ( select an-1.An from an-1in ( select a1.A2 from a1in ( select s.A1 from s in someSet ) )…) • 利用路径表达式,其查询可以缩短为: • select an.someAttr from anin someSet.A1.A2.….An

  45. 嵌套查询的数学表示 • 数学上的表示:结果集合可以表示为并集Un,其中Ui被递归定义成:

  46. 不同的Join类型 • 不同类型的联系 • 基于值的Join:关系查询传统的Join操作 • 标识Join • 函数Join

  47. 基于值的Join • 传统的连接操作,通过给定的Join属性的值的比较来联系对象 • 示例:查询两个BRep对象,它们之间,第二个变量为第一个的两倍 • select b1.name,b2.namefrom b1in BRep,          b2 in BRepwhere b1.weight * 2.0 = b2.weight+є • 对象b1,b2之间通过变量值来关联

  48. 标识Join--同一Jion • 标识Join--基于对象的相等,而不是值相等,因此,是基于OID值相等的连接 • 示例. • 谓词O1=O2--表示O1与O2OID相等而不是O1与O2的状态相等 • 谓词OЄ<Object>--当且仅当O是Object集合中的一个对象实例时为真,而不是说Object中有一个对象状态与O的状态相等

  49. 标识Join示例 • 父,母,子三个对象类型及其实例库 • type Man withextentionis      [name:  string;...;hasKids:{Child};];type WOMan with extention is      [name:  string;...;hasKids:{Child};];type Child with extention is      [name:  string;...;father:Man;mother:Woman;];

  50. 查询同一个父亲的两个孩子C1,C2 • select c1.name,c2.nameform c1in child;c2in childwhere c1.father=c2.father and c1!=c2 • 这里c1.father=c2.father是标识相等,而不是值相等 • 如果是这样的谓词 Where c1.father.name=c2.father.name and c1!=c2 --值相等查询

More Related