Transcript 此处下载
第八章 面向对象查询语言
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
Where For 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
Where Exists 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)
FromMovies 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)
FromMovies 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)
FromMovies 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使结果集成为列表
• 利用宿主语言的循环语句,逐个获取列表中
的元素
获取聚集的每个成员
movieList = Select m //List<Movie>
From Movies m
Order By m.title,m.year;
numberOfMovie = COUNT(Movies);
for(i=0;i<numberOfMovies;i++){
movie = movieList[i];
……
}
建立新对象
• 产生新的对象
– Select-from-where
– 类型构造符、常量、表达式
建立新对象
• 构造
x = Struct(a : 1,b : 2);
y = Bag(x,x,Struct(a : 3,b : 4));
建立新对象
• 查询(Select - From - Where)
Select
From
Where
Distinct StarPairs(star1:s1,star2:s2)
Stars s1,Stars s2
s1.addr = s2.addr And
s1.name < s2.name
构造对象类型StarPairs:Struct{star1:Star,star2:Star}
建立新对象
• 建立一个Movie对象
gwtw = Movie(title : “Gone With the Wind”,
year : 1939,
length : 239,
ownedBy : mgm);
SQL3中的元组对象
• OODBMS中OQL描述对象为结构的集合(或
者包),关系是次要的
• ORDBMS中关系是重要的,关系是核心
– Row Object (Row Type)
• 本质上就是元组(tuple)
– Abstract Data Type (ADT)
• 作为元组分量的对象
SQL3——行类型
• 定义元组类型
– 类似于ODL中的Class
• Create Row Type T(<分量说明>)
SQL3——行类型
Create Row Type AddressType(
streetChar(50),
city
Char(30)
);
Create Row Type StarType(
nameChar(30),
address AddressType
);
SQL3——具有行类型的关系
• OF TYPE <行类型名>
Create Table MovieStar OF TYPE StarType;
SQL3——访问行类型的分量
• 行类型是关系的分量,行类型本身包含分量
• 以“..”表示分量的分量(层次)
Select MovieStar.name,
MovieStar.address..street
From MovieStar
Where MovieStar.address..city = ‘SFO’
SQL3——行类型的引用
• 行类型可以被引用作为另一行类型的分量
• 通过具有引用类型的属性,直接引用对象
(元组)
• REF(T)
SQL3——行类型的引用
Create Row Type MovieType(
title
Char(30),
year
Integer,
inColor
Bit(1) );
Create Table Movie OF TYPE MovieType;
Create Row Type StarType(
name
Char(30),
address
AddressType,
bestMovie REF(MovieType) );
SQL3——行类型的引用
• 通过REF引用对象(元组),实现关系的联系
• 多对多的引用
SQL3——行类型的引用
Create Row Type MovieType(
title Char(30),
year Integer,
inColor Bit(1));
Create Row Type AddressType(
street Char(50),
city Char(30));
Create Row Type StarType(
name Char(30),
address AddressType);
Create Row Type StarsInType(
star REF(StarType),
movie REF(MovieType));
Create Table Movie OF TYPE MovieType;
Create Table MovieStar OF TYPE StarType;
Create Table StarsIn OF TYPE StarsInType;
SQL3——利用引用
• 利用引用来扩展SQL
• SQL3支持“->”,可以替代连接
• 若x是元组t的引用,且a是t的属性,则x->a就是
元组t中属性a的值
SQL3——利用引用
Select movie -> title
From StarsIn
Where star -> name = ‘Mel Gibson’
SQL3——引用的作用域
• 限定所作的引用是针对哪个关系进行的
SCOPE FOR <属性> IS <关系>
Create Row Type StarsInType(
star
REF(StarType),
movie
REF(MovieType));
Create Table StarsIn OF TYPE StarsInType
Scope For star Is MovieStar,
Scope For movie Is Movie;
SQL3——作为值的对象标识
• SQL3允许显式地引用OID
• 方法
–
–
–
–
在行类型中增加一个属性,使其引用所在的行类型
在建表时说明:
Values For <属性> ARE SYSTEM GENERATED
该属性可作为主码使用
SQL3——作为值的对象标识
Create Row Type MovieType(
movie_id REF(MovieType),
title
Char(30),
year
Integer,
inColor Bit(1));
Create Table Movie OF TYPE MovieType
Values For movie_id Are System Generated;
SQL3的抽象数据类型(ADT)
• ADT的定义
• ADT方法的定义
• 外部函数