700 likes | 889 Views
第八章 面向对象查询语言 Object-Oriented Query Languages. 概述. 面向对象 面向对象数据模型 面向对象方法中引入数据库的概念(持久化) 以面向对象的方法构造数据库 关系对象数据模型 关系数据模型中引入面向对象的概念 引入新的数据类型,作为类型扩展. 概述. 面向对象查询语言 OODBMS OQL ORDBMS SQL3. 概述. ODMG Object Database Management Group ODMG-93
E N D
第八章 面向对象查询语言Object-Oriented Query Languages
概述 • 面向对象 • 面向对象数据模型 • 面向对象方法中引入数据库的概念(持久化) • 以面向对象的方法构造数据库 • 关系对象数据模型 • 关系数据模型中引入面向对象的概念 • 引入新的数据类型,作为类型扩展
概述 • 面向对象查询语言 • OODBMS • OQL • ORDBMS • SQL3
概述 • ODMG • Object Database Management Group • ODMG-93 • 吸取OMG的COM(Common Object Model)、IDL(Interface Definition Language) • 增加数据库内容,形成OM、ODL • OQL • 力图成为OODBMS的标准
ODL中与查询相关的特性 • ODL(Object Definition Language) • 用面向对象的术语,说明数据库结构的标准语言 • 用于书写面向对象数据库的设计说明 • 可直接转换成对OODBMS的(实现)说明
ODL——对象的操作 • ODL,Interface • 属性(Attribute) • 该class的特性 • 联系(Relationship) • 该类对象与其他类对象的联系(引用) • 方法(Method) • 与类相关的函数,可作用与该类对象的函数 • 代码不是ODL的成分,由宿主实现
ODL——方法的说明 • 署名 • 方法的名字 • 返回值的类型 • 参数种类 • In • Out • InOut • 参数类型 • 异常(Exception)处理 • Raises(<异常名>)
ODL——方法的说明 Interface Movie Key(title,year) { …… //attributes & relationships float lengthInHours() Raises(noLengthFound); starNames(out Set<string>); otherNames(in Star,out Set<Movie>) Raises(noSuchStar); };
ODL——类的范围 • ODL的说明 • 是该类对象的当前集合名,类似于关系名 • extent <范围名> • 范围名可以与类名不一致 • 将以范围名被引用
ODL——类的范围 Interface Movie (extent Movies Key(title,year)) { …… //attributes & relationships float lengthInHours() Raises(noLengthFound); starNames(out Set<string>); otherNames(in Star,out Set<Movie>) Raises(noSuchStar); };
OQL • 对象查询语言 • OQL:Object Query Language • 以ODMG对象模型为基础的类似SQL的查询语言 • 作为OOP宿主语言的扩展 • OQL混入宿主语言(不是嵌入) • 完整描述:ODMG-93
OQL——实例 Interface Movie (extent Movies key(title,year)) { attribute string title; attribute integer year; attribute integer length; attribute enumeration(color,blackAndWhite) filmType; relationship Set<Star> stars inverse Star::starredIn; relationship Studio ownedBy inverse Studio::owns; }
OQL——实例 Interface Star (extent Stars key name) { attribute string name; attribute Struct Addr {string street,string city}address; relationship Set<Movie> starredIn inverse Movie::stars; }
OQL——实例 Interface Studio (extent Studios key name) { attribute string name; attribute string address; relationship Set<Movie> owns inverse Movie::ownedBy; }
OQL类型系统 • OQL中的类型与ODL一致 • ODL只涉及变量(类型) • OQL将涉及常量(值)
OQL类型系统 • 常量的表示 • 基本类型 • 原子类型 • 整数、浮点数、字符、字符串、布尔型 • 枚举类型 • 由ODL中定义的值
OQL类型系统 • 常量的表示 • 复杂类型 • Set(…) • Bag(…) • List(…) • Array(…) • Struct(…) • Struct(foo:bag(2,1,2),bar:“baz”)
OQL路径表达式 • 采用点‘.’的方式访问变量的分量 • 如果a表示属于类C的对象,p是该类的某个特性(属性、联系或方法),则a.p表示把p用于a的结果 • 如果p是属性,则a.p就是对象a的该属性值 • 如果p是联系,则a.p就是通过联系p与a相连的对象或对象的聚集 • 如果p是方法,则a.p就是把p用于a的结果
OQL路径表达式 • 例:如果myMovie是宿主语言的变量,其值是Movie对象,则 • myMovie.length(对象中的属性名)是该电影的长度 • myMovie.lengthInHours()(对象中的方法名)的值是实数,通过把方法lengthInHours()作用于对象myMovie的结果 • mymovie.stars(对象中的联系名)的值是通过联系stars与电影(对象)myMovie相连的Star对象的集合 • myMovie.starNames(myStars)本身不返回任何值,但以参数myStars作为输出,返回电影对象myMovie中的影星姓名(集)
OQL路径表达式 • myMovie.ownedBy.name表示什么?
OQL中的查询表达式 • 具有类似SQL的Select-From-Where格式 Select m.year From Movies m //为什么是Movies ? Where m.title = “Gone With the Wind” • 查询将产生对象的包(Bag)
OQL查询中消除重复 • 查询结果集是Bag,而不是Set,缺省为ALL • Distinct
OQL复杂的输出类型 • Select子句中的表达式 • 简单变量 • 任何表达式 Select Distinct Struct(star1:s1,star2:s2) From Stars s1,stars s2 Where s1.addr = s2.addr And s1.name < s2.name • Select star1:s1,star2:s2
OQL中的子查询 • 可在适于聚集的任何地方使用select-from-where表达式 • 可以出现在From中(如同SQL) Select Distinct s.name From (Select m From Movies m Where m.ownedBy.name = “Disney”) d, d.stars s
OQL对结果的排序 • 类似于SQL • Order By Select m From Movies m Where m.ownerdBy.name = “Disney” Order By m.length,m.title
OQL对结果的排序 (Select m From Movies m Where m.ownerdBy.name = “Disney” Order By m.length Desc ) [0:4]
OQL表达式的附加格式 • 表达式的构造形式 • 量词表达式 • 聚合表达式 • 分组表达式 • Having子句 • 集合运算
OQL表达式——量词表达式 • For All • 检测是否所有的集合成员都满足条件,返回True/False • For All x In S : C(x) • 集合S中的所有成员(每个x)均满足条件C(x) • 类似于SQL中的All
OQL表达式——量词表达式 • For All:仅在“Disney”公司的影片中出演的影星 Select s From Stars s WhereFor All m In s.starredIn : m.ownedBy.name=“Disney” relationship Set<Movie> starredIn inverse Movie::stars;
OQL表达式——量词表达式 • Exists • 检测是否至少有一个集合成员满足条件,返回True/False • Exists x In S : C(x) • 集合S中至少有一个成员(x)满足条件C(x) • 类似于SQL中的Exists
OQL表达式——量词表达式 • Exists:在“Disney”公司的影片中担任过角色的影星 Select s From Stars s WhereExists m In s.starredIn : m.ownedBy.name = “Disney” relationship Set<Movie> starredIn inverse Movie::stars;
OQL表达式——聚合表达式 • 聚合表达式,作用于其成员具有合适类型的聚集(Collection) • AVG //算术类型 • COUNT //任何聚集 • SUM //算术类型 • MIN //可比较类型 • MAX //可比较类型
OQL表达式——聚合表达式 Avg(Select m.length From Movies m)
OQL表达式——分组表达式 • Group By • 与SQL有些差异 Select std,yr, sumLength : SUM(Select p.m.length From partition p) From Movies m Group By std:m.ownedBy.name,yr:m.year
OQL表达式——分组表达式 • Group By • 格式: • Group By f1:e1,f2:e2,…,fn:en • 返回的是结构的集合 Struct(f1:v1,f2:v2,…,fn:vn,partition:P) • Select子句中的项,只能取自Group By结果中的域f1,f2,…,fn和partition
OQL表达式——分组表达式 Select Old,New, avgLength:Avg(Select p.m.length From partition p) From Movies m Group By Old:m.year <2000, New:m.year >= 2000
OQL表达式——Having子句 • Having子句与SQL类似 • 作用于partition,用来删除由Group By建立的某些组 • Having <条件> • 条件为True:输出 • 条件为False:不输出
OQL表达式——Having子句 Select std, yr, sumLength:SUM(Select p.m.length From partition p) From Movies m Group By std : m.ownedBy.name, yr : m.year Having SUM(Select p.m.length From partition p) > 120
OQL表达式——Having子句 Select std, yr, sumLength:SUM(Select p.m.length From partition p) From Movies m Group By std : m.ownedBy.name, yr : m.year Having Max(Select p.m.length From partition p) > 120
OQL表达式——集合运算符 • 并(Union)、交(Intersect)、差(Except)运算 • 集合?——含有Distinct • 包?——不含Distinct • OQL与SQL略有不同 • 可以是集合:参加运算的参数均为集合 • 也可以是包:参加运算的参数中包含包
OQL表达式——集合运算符 (Select Distinct m From Movies m,m.stars s Where s.name = “Harrison Ford”) Except (Select Distinct f From Movies f Where f.ownedBy.name = “Disney”)
OQL表达式——集合运算符 • 包的并、交、差规则 • 若x在B1中出现n1次,在B2中出现n2次 • B1B2中,x出现n1+n2次 • B1B2中,x出现min(n1+n2 )次 • B1B2中, • 若n1 <= n2,x出现0次 • 若n1 > n2,x出现n1 - n2次
Examples : ODL Interface A (extent Aext) { attribute string aName; relationship Set<B> myBs inverse B::myA;} Interface B (extent Bext) { attribute string bName; relationship A myA inverse A::myBs; relationship C myC inverse C::myBs;} Interface C (extent Cext) { attribute string cName; relationship Set<B> myBs inverse B::myC;}
Examples Q1: Select bb.myC.cName From Aext aa, aa.myBs bb Where aa.aName = “sue” Q2: Select bb.myC.cName From Bext bb Where bb.myA.aName = “sue”
Examples Q1: Select cc.cName From Cext cc, cc.myBs bb Where bb.myA.aName = “sue” Q2: Select cc.cName From Cext cc Where Exists bb In Bext : bb.myA.aName = “sue”
Examples Q1: Select x : COUNT(aa.myBs) From Aext aa Q2: Select x : COUNT(partition) From Bext bb Group By bb.myA
OQL中对象的赋值和建立 • ODL/OQL能很方便地与宿主语言衔接,混入宿主语言之中 • OOP的宿主语言,扩充了OQL的OOP
OQL编程——变量赋值 • OQL与OOP宿主语言体系是匹配的 • 直接可以使用OQL的结果对象 oldMovies = Select Distinct m From Movies m Where m.year < 1920 Set<Movie> oldMovies
从聚集中提取元素 • OQL的结果集(即使只有一个对象) • 集合 • 包 • ELEMENT运算符 • 获得仅有单个对象的结果集中的成员 gwtw = ELEMENT(Select m From Movies m Where m.title = “Gone With the Wind”);
获取聚集的每个成员 • 类似于SQL中的Cursor,但比Cursor便捷 • OQL结果集(集合或包)→列表 • OQL中的Order By使结果集成为列表 • 利用宿主语言的循环语句,逐个获取列表中的元素