30
1 Teil I Teil I Datenmodelle Datenmodelle Kapitel 6: Objektorientierte Anfragesprachen

1 Teil I Datenmodelle Kapitel 6: Objektorientierte Anfragesprachen

Embed Size (px)

Citation preview

Page 1: 1 Teil I Datenmodelle Kapitel 6: Objektorientierte Anfragesprachen

1

Teil ITeil IDatenmodelleDatenmodelle

Kapitel 6: Objektorientierte Anfragesprachen

Page 2: 1 Teil I Datenmodelle Kapitel 6: Objektorientierte Anfragesprachen

2

Der ODMG-Standard für ODBMS ODMG = Object Database Management Group, gegründet

1991 als Arbeitskreis von ODBMS-Herstellern. Ziel: Entwicklung eines Standards für die objektorientierte

Datenhaltung (ODBMS, ORDBMS, ...). Stand: ODMG-Standard Version 3.0 (2000) definiert:

sprachneutrales Objektmodell, Object Definition Language (ODL), Object Interchange Format

(OIF) und Object Query Language (OQL), Sprachanbindungen des Objektmodells an C++, Java,

SmallTalk. Mehrheit der Produkte unterstützt ODMG, allerdings oft

ohne ODL, OIF, OQL.

Page 3: 1 Teil I Datenmodelle Kapitel 6: Objektorientierte Anfragesprachen

3

Object Definition Language (ODL) Im Gegensatz zu SQL sind DML und DDL im ODMG-

Standard getrennt: Schema einer ODMG-Datenbasis wird in ODL spezifiziert. (Interaktive) Datenmanipulation erfolgt in OQL.

ODL ist reine Daten-Definitionssprache, Programmierung von Methoden muss in Wirtssprache Java, C++ oder SmallTalk erfolgen.

Praxisrelevanz von ODL begrenzt, da DB-Schema oft per Schemagenerator direkt aus Applikation gewonnen wird.

Page 4: 1 Teil I Datenmodelle Kapitel 6: Objektorientierte Anfragesprachen

4

Kollektionstypen ODMG-Objektmodell definiert folgende Literal- bzw.

Klassenkonstruktoren für Kollektionen (t,v beliebige Typen): set<t>, Set<t>: Ungeordnete Menge ohne

Duplikate bag<t>, Bag<t>: Ungeordnete Menge mit

Duplikaten list<t>, List<t>: Geordnete Menge mit Duplikaten array<t>, Array<t>: Funktion von {1, 2, ..., n} nach t

Alle Kollektionstypen implementieren das Interface Collection mit (u.a.) folgenden Operationen:

insert_element() remove_element() is_empty() cardinality() contains_element() create_iterator()

Page 5: 1 Teil I Datenmodelle Kapitel 6: Objektorientierte Anfragesprachen

5

Konsistenz: Schlüssel

class Vielflächner (extent alleVielflächner key vName ){ attribute string vName;

attribute float oberfläche;relationship set<Fläche> flächen

inverse Fläche::körper;void translation(in Punkt p) };

Bedeutung einer key-Spezifikation: ODBMS erzwingt, dass Vielflächner-Instanzen mit

verschiedenen Objekt-Identifikatoren auch verschiedene vname-Werte haben.

Objekt-Identifikator ist dennoch separat von vname-Wert (letzterer kann sich ändern, ersterer nicht).

Page 6: 1 Teil I Datenmodelle Kapitel 6: Objektorientierte Anfragesprachen

6

Referenzielle Konsistenz

class Vielflächner (extent alleVielflächner key vName ){ attribute string vName;

attribute float oberfläche;relationship set<Fläche> flächen

inverse Fläche::körper;void translation(in Punkt p) };

class Fläche {relationship set<Vielflächner> körper

inverse Vielflächner::flächen; }

Nur zweistellige Beziehungen können spezifiziert werden. Unterschied zwischen Beziehungen und einfachen

objektwertigen Attributen: ODBMS sorgt bei Beziehungen für Wahrung der referenziellen Konsistenz.

Page 7: 1 Teil I Datenmodelle Kapitel 6: Objektorientierte Anfragesprachen

7

Object Query Language (OQL) ODMG-Standard spezifiziert Object Query Language (OQL)

als deklarative Anfragesprache für ODMG-Objektmodell. Entwurfsprinzipien:

Weitgehende Kompatibilität mit SQL-92. Strenge Typisierung: Alle Ausdrücke haben statisch

bestimmbare Typen innerhalb des ODMG-Typsystems. Orthogonalität: Alle Ausdrücke können, soweit ihre Typen

verträglich sind, beliebig kombiniert werden; keine syntaktischen Ausnahmen und Sonderstellungen für spezielle Typen.

Wahrung der Objektkapselung: Objektänderungen nur durch Aufruf entsprechender Methoden.

In existierenden ODBMS allerdings noch nicht sehr verbreitet, daher im Folgenden nur kursorische Präsentation.

Page 8: 1 Teil I Datenmodelle Kapitel 6: Objektorientierte Anfragesprachen

8

Beispielschema

class Punkt( extent allePunkte ) { attribute float x; attribute float y; attribute float z; void translation(in Punkt p);};

class Kante {( extent alleKanten ) { attribute Punkt p1; attribute Punkt p2; void translation(in Punkt p); float länge()};

class Fläche {( extent alleFlächen ) { attribute string fName; attribute set<Kante> kanten; relationship Vielflächner körper inverse Vielflächner::flächen; void translation(in Punkt p); float fläche()};

class Vielflächner( extent alleVielflächner key vName ) { attribute string vName; attribute float oberfläche; relationship set<Fläche> flächen inverse Fläche::körper; void translation(in Punkt p);};

class Quader extends Vielflächner( extent alleQuader ) { float volumen();};

Page 9: 1 Teil I Datenmodelle Kapitel 6: Objektorientierte Anfragesprachen

9

Einfache OQL-Ausdrücke (1)Literale und Objekte können direkt konstruiert werden; gültige

Ausdrücke und ihre Typen sind z.B.: "Quader77":

string struct(x:1.0, y:2.0, z:0.0)

struct<x: float, y: float, z: float > Punkt(x:1.0, y:2.0, z:0.0)

Punkt Kante(Punkt(x:1.0, y:2.0, z:0.0), Punkt(x:1.0, y:2.0, z: 0.0))

Kante bag(1,1,2,3,3)

bag<unsigned short> set(1,2,3,4,5)

set<unsigned short>

Page 10: 1 Teil I Datenmodelle Kapitel 6: Objektorientierte Anfragesprachen

10

Einfache OQL-Ausdrücke (2) Klassen mit Extensionen:

Extensionen für Klassen nur, wenn im Schema vereinbart allePunkte

set<Punkt>

liefert Menge der dauerhaften Instanzen der Klasse Punkt Klassen ohne Extension:

Dann sind alle Instanzen nur indirekt durch Referenzierung zugänglich

Beispiel: Wenn Punkt keine Extension hätte, wären Punkte nur noch z.B. über Kante erreichbar

Page 11: 1 Teil I Datenmodelle Kapitel 6: Objektorientierte Anfragesprachen

11

Einfache OQL-Ausdrücke (3) Funktionen über Ausdrücken ergeben wieder Ausdrücke,

z.B. abs, not

t t t numerischer bzw. boolescher Typ +, -, *, /, mod

t t t t numerischer Typ Aggregatfunktionen über Ausdrücken sind auch möglich

count:collection<t> unsigned long t beliebig

min, max, sum, avg:collection<t> t t numerisch

Beachte: collection ist Obertyp von set, bag, list etc. und somit substituierbar

Page 12: 1 Teil I Datenmodelle Kapitel 6: Objektorientierte Anfragesprachen

12

OQL-Pfadausdrücke Attribut- und Methodenzugriffe erfolgen mit "."-Operator:

p.xfloat p sei Verweis auf Punktobjekt

Pfadausdrücke können mehrere Stufen aufweisen:k.p1.xfloat k sei Verweis auf Kanteobjekt

Trifft gleichermaßen zu auf tieferes Eindringen in ein komplexes Objekt entlang struct oder auf Fortschreiten über mehrere Objekte entlang der Referenzen (dann automatisches Dereferenzieren).

Bei Methoden können Parameterlisten angegeben werden:

k.translation( Punkt(x:1.0, y:2.0, z:0.0) )void

Page 13: 1 Teil I Datenmodelle Kapitel 6: Objektorientierte Anfragesprachen

13

OQL-Bedingungen Elementare Vergleiche (!=, =, <, >, like) und boolesche

Kombinationen wie in SQL. Etwas andere Form der Quantifizierung:

exists x in e : c

for all x in e : c

wobei e Ausdruck mit Kollektionstyp und c Bedingung, z.B. (f Verweis auf Flächenobjekt):exists k in f.kanten : k.p1.x = 0.0

Diverse Kurzformen existieren als Zugeständnis an SQL:x in e als Kurzform für exists y in e : x = y

x all e als Kurzform für for all y in e : x y

x any e als Kurzform für exists y in e : x y

Page 14: 1 Teil I Datenmodelle Kapitel 6: Objektorientierte Anfragesprachen

14

Select-Ausdrücke Gegenüber SQL geringfügig andere Syntax:

select [distinct] e from [x1 in] e1, [x2 in] e2, ..., [xn in] en

[where c][order by f1, ..., fm]

e1...en Ausdrücke mit Kollektionstypen,e beliebiger Ausdruck,f1...fm Ausdrücke mit atomaren oder strukturierten Literaltypen,c Bedingung undx1...xn optionale Variablendeklarationen.

Typ eines select-Ausdrucks ist (mit t = Typ von e):list<t> wenn order by angegeben wurde,

set<t> wenn distinct, aber nicht order by angegeben wurde,

bag<t> wenn weder distinct noch order by angegeben wurde.

Page 15: 1 Teil I Datenmodelle Kapitel 6: Objektorientierte Anfragesprachen

15

Semantik von Select-Ausdrücken (1) Semantik ist analog zu SQL. Auswertung eines Select-Ausdrucks (vereinfachte Version):

1. Werte Ausdrücke e1...en in from-Klausel aus und konvertiere Ergebnisse in Bags b1...bn.

2. Kartesisches Produkt: Bilde alle Tupel x1...xn mit xi bi.

3. Eliminiere Tupel, die Bedingung c aus where-Klausel nicht erfüllen.

4. Werte auf jedem verbleibenden Tupel Ausdruck e aus select-Klausel aus und füge Resultat in Ergebnis ein.

5. Falls distinct spezifiziert wurde, eliminiere Duplikate6. Falls order by spezifiziert wurde, sortiere Ergebnis nach

Werten der Ausdrücke f1...fm.

Page 16: 1 Teil I Datenmodelle Kapitel 6: Objektorientierte Anfragesprachen

16

Semantik von Select-Ausdrücken (2) Gruppierung analog zu SQL:

select … from … where …

[group by y1 : g1, y2 : g2, ..., yn : gn]

[having c]

g1...gn Ausdrücke mit Kollektionstypen, c Bedingung und y1...yn nichtoptionale Bezeichner.

Angabe von group by wird jedoch nicht benötigt, da geschachtelte Ergebnisse direkt spezifiziert werden können

Beispiel: Typset<struct<vName: string, punkte: set<Punkt>>>beschreibt Punkte gruppiert nach Namen von Vielflächnern.

Page 17: 1 Teil I Datenmodelle Kapitel 6: Objektorientierte Anfragesprachen

17

Semantik von Select-Ausdrücken (3) Erweiterte Syntax (Ausschnitt):

select e(x1, x2, …, xn , xn+1, …, xn+p)

from x1 in e1(xn+1, …, xn+p),x2 in e2(x1, xn+1, …, xn+p),x3 in e3(x1, x2, xn+1, …, xn+p),…,xn in en(x1, x2, …, xn-1, xn+1, …, xn+p)

Was bei Abhängigkeiten zwischen den xi? Auswertung eines select-Ausdrucks (erweiterte Version):

1. Werte Ausdrücke e1...en in from-Klausel aus und konvertiere Ergebnisse in Bags b1...bn.

2. Bilde alle Tupel x1...xn mit xi bi wobei die Abhängigkeiten zwischen den xi sich nun als Joins auswirken.

Existieren keine Abhängigkeiten, degeneriert dieser Schritt wieder zu einem einfachen kartesischen Produkt.

3.-6. bleiben gleich.

Page 18: 1 Teil I Datenmodelle Kapitel 6: Objektorientierte Anfragesprachen

18

OQL-Anfragen (1) Alle Punkte, die auf der Null-Ebene liegen:

select struct (ex : x, ey : y) from allePunkte where z = 0

Rückgabetyp: bag<struct<ex:float, ey:float>> Alle Kanten, die zu Flächen mit mindestens vier Kanten

gehören:select struct (kp1 : k.p1, kp2 : k.p2)from f in alleFlächen, k in f.kanten where count (f.kanten) >= 4

Rückgabetyp: bag<struct<kp1:Punkt, kp2:Punkt>>

Impliziter Join!

Page 19: 1 Teil I Datenmodelle Kapitel 6: Objektorientierte Anfragesprachen

19

OQL-Anfragen (2) Dieselbe Anfrage, aber gruppiert nach Flächen:

select struct (fläche: f.fName, punkte:(select struct (kp1 : p1,

kp2 : p2) from f.kanten))

from f in alleFlächenwhere count (f.kanten) >= 4

Rückgabetyp:

bag<struct<fläche:string, punkte:bag<struct<kp1:Punkt,kp2:Punkt>>>>

Beachte: Gruppierung ohne group by

Page 20: 1 Teil I Datenmodelle Kapitel 6: Objektorientierte Anfragesprachen

20

OQL-Anfragen (3) Ergebnis kann Resultat von Operatoraufrufen enthalten

z.B.:select volumen()from alleQuader

Länge aller Kanten von großen Flächen:select k.längefrom f in alleFlächen, k in f.kanten where f.fläche > 100.0

Vielflächner mit großen Flächen:select vNamefrom alleVielflächnerwhere for all f in flächen : f.fläche() > 100.0

Page 21: 1 Teil I Datenmodelle Kapitel 6: Objektorientierte Anfragesprachen

21

OQL-Anfragen (4) Aggregierung nach Gruppen, z.B. zuerst Gruppierung der

Quader nach Oberfläche, dann Berechnung des mittleren Volumens über alle Quader mit dieser Oberfläche, dies aber nur für Oberflächen über 20:

select struct (ofläche, dvolumen: avg( volumen() )from alleQuadergroup by ofläche : oberflächehaving oberfläche >= 20.0

Rückgabetyp:bag<struct<ofläche:float, dvolumen:float>>

Page 22: 1 Teil I Datenmodelle Kapitel 6: Objektorientierte Anfragesprachen

22

OQL-Anfragen (5) Auch die Sortierungsklausel existiert in OQL, z.B.:

select from alleQuaderorder by oberfläche desc, volumen() asc

Es kann nach mehreren Attributen bzw. Methodenresultaten sortiert werden Aufsteigend: asc (Voreinstellung) Absteigend: desc

Page 23: 1 Teil I Datenmodelle Kapitel 6: Objektorientierte Anfragesprachen

23

OQL-Anfragen (6) Gesamtzahl aller Kanten, die aus dem Nullpunkt

entspringen:count( select

from alleKantenwhere p1.x = 0.0and p1.y = 0.0 and p1.z = 0.0)

Ergebnistyp:unsigned long

Bemerkung: OQL erlaubt (als Tribut an SQL) auch Syntaxselect count ()from alleKanten where p1.x = 0.0 and p1.y = 0.0 and p1.z = 0.0)

Page 24: 1 Teil I Datenmodelle Kapitel 6: Objektorientierte Anfragesprachen

24

OQL-Anfragen (7) Liste aller Flächen mit Umfang über 1000:

select ffrom f in alleFlächenwhere 1000 < sum( select k.länge

from k in f.kanten) Ergebnistyp:

bag<Fläche>

Page 25: 1 Teil I Datenmodelle Kapitel 6: Objektorientierte Anfragesprachen

25

Vordefinierte Anfragen Anfragen können in OQL parametrisiert und vordefiniert

werden, z.B.:define oberflächeZuName(x) as

select oberfläche from alleVielflächner

where vName = x

oberflächeZuName(x) kann jetzt in anderen Anfragen wiederverwendet werden.

Page 26: 1 Teil I Datenmodelle Kapitel 6: Objektorientierte Anfragesprachen

26

OQL-Anbindung an Java (1) Java als Beispiel für die Einbettung von OQL in eine

Programmiersprache Die OQL-Einbettung in Java ist teilweise mit dynamischem

SQL zu vergleichen OQL-Anfrage wird als Zeichenkette angegeben OQL kann von Java aus auf zwei Wegen angesprochen

werden: Mit einer Methode der Collection-Schnittstelle Über die generische OQLQuery-Klasse

Page 27: 1 Teil I Datenmodelle Kapitel 6: Objektorientierte Anfragesprachen

27

OQL-Anbindung an Java (2) Ausschnitt aus der Collection-Schnittstelle:

interface Collection { Collection query(String predicate); ...}

Beispiel (alle Vielflächner, die Fünfecke enthalten):

Set körperMitfünfEck = (Set)meineVielflächner.query(

“exists f in flächen : count(f.kanten) = 5“);

Äquvalente OQL-Query:select from meineVielflächnerwhere exists f in flächen : count(f.kanten) = 5

Diese Form der Anfrage legt den select- und from-Teil der Anfrage bereits durch den Elementtyp der Kollektion fest

Page 28: 1 Teil I Datenmodelle Kapitel 6: Objektorientierte Anfragesprachen

28

OQL-Anbindung an Java (3) Die Verwendung der query-Methode ist zwar sehr einfach,

doch hat sie einige Nachteile: Anfragen können nicht parametrisiert werden

Ausnahme: Anfragen über dynamisch zusammengebaute Zeichenketten

DBMS bekommt jedoch immer ihm unbekannte Zeichenketten, die immer neu zu analysieren und optimieren sind!

Anfragen können nicht wiederverwendet werden Auch hier gilt: Wiederverwendung über Zeichenketten ist nur die

halbe Lösung. Das DBMS bekommt davon nichts mit.

Beispiel: Alle Vielflächner, die Sechsecke enthalten ... Alle Vielflächner, die n-Ecke enthalten

Page 29: 1 Teil I Datenmodelle Kapitel 6: Objektorientierte Anfragesprachen

29

OQL-Anbindung an Java (4) Diese Nachteile behebt die generische OQLQuery-

Schnittstelle:interface OQLQuery { public create(String query); public bind(Object parameter); public Object execute(); }

Ein OQLQuery-Objekt wird zunächst mittels einer Fabrikmethode des DBMS erzeugt.

create() erzeugt eine Anfrage wie bei der query-Methode, ohne sie jedoch auszuführen, Parameter haben die Syntax $1, $2, $3 etc.

bind() bindet aktuelle Parameter an die formalen, wobei die Reihenfolge eine Rolle spielt: beim ersten Aufruf wird das Parameterobjekt an $1 gebunden, usw.

execute() führt die Anfrage schließlich aus, und liefert eine passende Kollektion in Form eines Objektes zurück.

Page 30: 1 Teil I Datenmodelle Kapitel 6: Objektorientierte Anfragesprachen

30

OQL-Anbindung an Java (5)

Beispiel für den Einsatz von OQLQuery: Liefere alle Vielflächner, die n Ecken enthalten und eine gewisse

Mindestoberfläche vorweisen können! // Java// statische (einmalige) InitialisierungOQLQuery query = dbms.newOQLQuery(); query.create(“ select * from alleVielflächner where exists f in flächen : count(kanten) = $1 and oberfläche >= $2“);...

// Methode mit Parameterübergabe und Ausführungpublic Set vielFlächnerMitNEcken(long n, float f) { Long anzahl = new Long(n); Float minOberfläche = new Float(f); query.bind(anzahl); query.bind(minOberfläche); return (Set)query.execute();

};