aaa Kap. 7: ODMG - Standard für Objektorientierte DBMS ODMG 2.0 (Object Database Management Group): Zusammenschluss von Herstellern objektorientierter DB-Produkte (Voting Members z.B. Object Design Inc., Objectivity Inc., POET Software, Sun Microsystems; Vorsitz Rick Cattell) Grober Vergleich von RDBMS und ODBMS als anfängliche Wunschvorstellung: Application Data Structures Copy and Translation Relational Representation RDBMS IS-K2000 Transparent ODBMS Data Transfer ODMG2.0-1 ODBMS gegenüber RDBMS • Ursprüngliche Zielsetzung von ODBMS (wie Bild vorher): Kein “Impedance Mismatch”, Programmiersprache = Datenbanksprache • Daher zunächst keine Wirtsprachen-unabhängige Datendefinition, Datenabfrage und Datenmanipulation wie es in SQL ist. • Vorteil: homogene Entwicklungsumgebung für Entwurf und Entwicklung von IS • Nachteile: – eine Datenbank kann nicht von mehreren Anwendungsprogrammiersprachen angesprochen werden, – ein ODBMS eines Herstellers kann nicht durch ein ODBMS eines anderen Herstellers ersetzt werden, es sei denn, die gleiche Programmiersprache wird verwendet (Widerpruch zur Realität: Smalltalk, C, C++, Java,...) • ODMG 2.0 enthält daher einen Vorschlag für – ODL = sprachunabhängige (stand-alone) Objektdefinition – OQL = sprachunabhängige (stand-alone) Objekt-Abfragesprache – keine OML, stattdessen Standard für C++OML, SmalltalkOML, JavaOML, sowie die Einbettung der ODL und OQL in diese Sprachen IS-K2000 ODMG2.0-2 1 aaa 7.1 Objekt-Definition (ODL) • Typen im Vergleich mit dem RMSDM: ODMG enthält mehr Typen als das RMSDM. Es sind einige wichtige Objekttypen vorgefertigt (z.B. Datum, Zeit, Zeitintervall). Ausserdem gibt es nicht nur den Set-Konstruktor, sondern auch Bag, List, Array und Dictionary. Dazu kommt, dass die oben genannten Typen hinsichtlich Kopiersemantik (“Literal_type”) bzw. Referenzsemantik (“Object_type”) praktisch zweifach auftreten. • Übersicht: Types Literal_type Object_type Atomic_literal Atomic_object Collection _literal Collection_object Structured_literal Structured_object ODMG2.0-3 IS-K2000 ODMG-Typen ::= long, short, unsigned long, unsigned short, float, double, boolean, octet, char, string, enum<> • Collection_literal ::= set<>, bag<>, list<>, array<>, dictionary<> • Structured_literal ::= structure<> , date, time, timestamp, interval • Atomic_literal ::= benutzerdefiniert durch interface{} und class {} • Atomic_object • Collection_object ::= Set<>, Bag<>, List<>, Array<>, Dictionary<> • Structured_object::= Date, Time, Timestamp, Interval Legende: Typen des RMSDM Collection_object unterscheidet sich vom Collection_literal durch Referenzsemantik bei Zuweisungen. Also ist unter Verwendung von Surrogaten (s. RMSDM): Set<> = surr(set<>)), entsprechend bei Bag (Menge mit Duplikaten), List, Array und Dictionary (Liste von Attribut-Wertpaaren). Analog ist der Zusammenhang zwischen Structured_literal und Structured_object. IS-K2000 ODMG2.0-4 2 aaa Typdefinitionen und ISA für Atomic_objects Typdefinition ist zusammengesetzt aus • INTERFACE • CLASS Definitionen. Leider ist diese Unterscheidung unklar und (noch) nicht konsequent. Der Standard sucht eine Klarheit durch folgendes Bild: Interface Class literals Abstraktes Verhalten Abstrakter Zustand (Operationen) (“Properties”) IS-K2000 ODMG2.0-5 INTERFACE versus CLASS • INTERFACE ist die Beschreibung eines Atomic_object Typs unter Verwendung von Properties und Operations. Zu einem Interface gibt es keine Instanzen. Ein Interface dient der Beschreibung der Schnittstelle mehrerer Typen. • CLASS ist die Beschreibung eines Atomic_object Typs unter Verwendung von – höchstens einer (Super-)Class-Beschreibung (IS-A), – keiner, einer oder mehrerer Interface-Beschreibungen (“HAS-A”), – einer EXTENT und KEY- Festlegung. – Properties- und Operations-Deklarationen. Klassen werden also instanziiert, die Instanzen finden sich im Extent der Klasse. Bezüglich der Key-Festlegung werden Duplikate im Extent verhindert. Beobachtung: Im Vergleich zum RMSDM grob folgende Entsprechung (besonders hinsichtlich des ODMG-Class-Extents) RMSDM-Typ ==> ODMG-Interface RMSDM-Klasse (benutzerdefiniert) ==> ODMG-Class (-Extent) IS-K2000 ODMG2.0-6 3 aaa Attribute, Beziehungen und Methoden Ein Atomic_object Typ wird beschrieben durch – Properties: Attribute und Beziehungen. • Attribut ist uni-direktional, d.h. eine Funktion (im RMSDM-Sinn), die nicht invertiert ist, daher insbesondere häufig einen Wertebereich mit Literal-Typ hat. Objektwertige Attribute sind jedoch auch zugelassen. Es ist allerdings besser, ein solches Attribut als Beziehung zu modellieren. • Beziehung ist bi-direktional, d.h. Funktion mit Inverser (im RMSDM-Sinn). – Operations: Methoden, die durch ihre Signatur beschrieben werden, insbesondere durch zusätzliche Input (“in”) und Output (“out”, “inout”) -Parameter. Standard-Inputparameter ist die Objekt-Instanz, auf der die Methode aufgerufen wird. Bemerkung: Im Basis-Objektmodell werden Properties und Operations nicht unterschieden, sondern einheitlich durch Funktionen dargestellt. ODMG2.0-7 IS-K2000 Beispiel Studierende {interface} adr name : string ETHNr : string Angestellter Adresse 1 Student strasse : string 1 ort : string plz : short Gehalt name : string AHVNr : string adr gehalt 1 brutto : float währung erhöhen() Professor Doktorand doktorvater 1 rang:Professur 0..* {ordered} 1 dozent setzt_voraus 0 .. * {ordered} betreut hört 0..* Vorlesung 1 .. * 0..* titel : string nummer:string 0..* liest ist_angeboten() IS-K2000 ODMG2.0-8 4 aaa ODL-Typdefinitionen - Vorlesung class Vorlesung ( extent Vorlesungen key nummer ) { attribute string titel; attribute string nummer; relationship Professor dozent inverse Professor::liest; relationship list<Doktorand> betreut_von inverse Doktorand::betreut; relationship list<Vorlesung> setzt_voraus inverse Vorlesung::ist_voraussetzung_für; relationship set<Vorlesung> ist_voraussetzung_für inverse Vorlesung::setzt_voraus; boolean ist_angeboten ( in unsigned short semester ); }; ODMG2.0-9 IS-K2000 ODL-Typdefinitionen - Hilfsklassen class Gehalt { readonly attribute float brutto; readonly attribute enum Währung {CHF,EUR,…} währung; void erhöhen ( in float betrag, in Währung was ); }; struct Adresse { attribute string attribute string attribute short }; IS-K2000 strasse; ort; plz; ODMG2.0-10 5 aaa ODL-Typdefinitionen - Angestellter und Professor class Angestellter ( extent Angestellte key AHVNr ) { attribute string name; attribute string AHVNr; attribute Adresse adr; attribute Gehalt gehalt; }; class Professor extends Angestellter (extent Professoren) { attribute enum Professur {Voll, Assistent} rang; relationship set<Vorlesung> liest inverse Vorlesung::dozent; }; IS-K2000 ODMG2.0-11 ODL-Typdefinitionen - Student und Doktorand interface Studierende { attribute string name; attribute string ETHNr; attribute Adresse adr; }; class Student : Studierende ( extent Studenten key ETHNr ) { attribute string name; attribute string ETHNr; attribute Adresse adr; attribute set<Vorlesung> hört; }; class Doktorand extends Angestellter : Studierende (extent Doktoranden) { attribute string ETHNr; attribute Professor doktorvater; relationship set<Vorlesung> betreut inverse Vorlesung::betreut_von; }; IS-K2000 ODMG2.0-12 6 aaa Klassen als Implementierung von Schnittstellen? • Einer Interface-Definition werden keine Instanzen zugeordnet. Es gibt daher kein allgemeineres Objekt, von dem ein spezielleres in der (ODMG) -ISA Beziehung Properties (Attributwerte, Beziehungspartner) erben kann. Es wird nur die Art der Eigenschaften und Beziehungen festgelegt. • Zu einer Class-Definition gibt es Instanzen in dem dazu eingeführten Extent. Über die “extends”-Anweisung bekommt daher eine “Subclass” nicht nur die Art sondern auch die Werte der “Properties” also der Attributwerte und Beziehungspartner. Zu jeder Instanz einer “subclass” gibt es genau eine Instanz in der übergeordneten “class”. Mehrfachvererbung von Properties ist ausgeschlossen. • Wenn in einer Interface-Definition I “Properties” spezifiziert sind, so müssen diese in einer Klasse C, für die C “HAS-A” I gilt, “nachgereicht” werden, sofern sie nicht von der übergeordneten Class geerbt werden. Siehe Beispiel TA. Man sagt in diesem Zusammenhang, dass die Klasse C eine “Schnittstelle für I implementiert”. Dies ist insofern irreführend, dass über eine “class”-Definition ein abstrakter Datentyp spezifiziert wird und keine Implementierung. • Für ODMG- (oder Java-) Interfaces könnte man auch “abstrakte Klasse” sagen IS-K2000 ODMG2.0-13 7.2 OQL - Objektabfragesprache • OQL ist eine Vereinigung aus (NF2-) relationalen Konstrukten und solchen des Basisobjektmodells, in einer dem vorgestellten PseudoSQL ähnlichen Syntax. • OQL enthält SQL-92 (den Anfrageteil ohne DML) • OQL enthält Konstrukte für einzelne Objekte, nicht nur für Kollektionen. • OQL kann auch - wie SQL - embedded (in C++, Smalltalk, Java) in Anwendungsprogrammen, nicht nur “stand-alone” verwendet werden. • Syntaxdiagramme finden sich als Ergänzungsblätter (siehe auch die WWW-Seiten dieser Vorlesung) • Durch das Bemühen, SQL-kompatibel zu sein, verliert man Eleganz. Die Unterstützung von vielen Collection Types geht auf Kosten der Einfachheit. • Es werden im folgenden einige typische Beispiele gegeben: IS-K2000 ODMG2.0-14 7 aaa Objekte ansprechen • Beschränkung im folgenden auf Extent-Namen als Zugang zur Objektbank (es gibt auch persistente Namen von Einzelobjekten) • Die entsprechenden Typdefinitionen müssen vorhanden sein. • Ergebnistyp leitet sich aus der Anfrage ab • Beispiele: 1) Menge der Namen aller Studenten : distinct ( select s.name from s in Studenten ) Ergebnis ist vom Typ Literal_set<string> ,bzw. Literal_bag<string> falls ohne distinct. 2) Name und Studentennummer aller Studenten: select struct ( n:s.name, id:s.ETHNr ) from s in Studenten Ergebnis ist vom Typ Literal_bag< struct<string, integer> > IS-K2000 ODMG2.0-15 Einzelobjekte und Objekte Generieren • Beispiele: 1) Generieren einer Instanz vom Typ Professor: Professor (name:”Einstein”, AHVNr:“123”, rang:Voll) 2) Zugriff auf Einzelobjekt über Schlüssel: element(select p from p in Professoren where p.AHVNr=“123”) 3) Verwendung eines solchen Objekts beim Generieren einer Vorlesung: Vorlesung ( titel: “Relativitätstheorie für Vorgerückte”, nummer: “95-610”, dozent: element ( select p from p in Professoren where p.AHVNr = “123” ), betreut_von: select d from d in Doktoranden where d.doktorvater = element (…), … ) IS-K2000 ODMG2.0-16 8 aaa Pfadausdrücke und Ausgabe von Werten • Sei o Objekt, o.A1.A2. ... .Ak ist ein Pfadausdruck für Ak(...A2(A1(o))), wenn alle Ai einwertige Funktionen (Attribute oder Beziehungen) sind. • Falls Ai mengen- (oder bag-, listen- )wertig ist, so muss ein Iterator der Form vi in o.A1.A2. … .Ai verwendet werden, der die Elemente der Menge durchläuft. Beispiel: Ermittle zu jedem Doktoranden seinen Namen und den seines Doktorvaters, sowie die Namen, Nummern und Dozenten der von ihm betreuten Vorlesungen. select struct( name: d.name, betreuer: d.doktorvater.name, lectures: select struct ( t: v.titel, n: v.nummer, p: v.dozent.name ) from v in d.betreut ) from d in Doktoranden ODMG2.0-17 IS-K2000 Aufruf von Operationen und generische Operationen • Via Operationen kann man unter anderm ändern. • Beispiele: 1) Erhöhe das Gehalt von Professor Einstein: (element (select p from p in Professoren where p.AHVNr = “123” ) ).gehalt.erhöhen(1000,CHF) (Methode erhöhen() kann neben Gehalt evtl. auch weitere “Properties” ändern!) 2) Ermittle die erste Vorlesung, die Voraussetzung für die Vorlesung IS-K ist (unter der Annahme, dass die Nummerierung von Listen bei 0 beginnt): (element ( select v from v in Vorlesungen where v.titel = “IS-K”) ).setzt_voraus[0] weitere Geheimnisse: siehe praktische Übung IS-K2000 ODMG2.0-18 9 aaa 7.3 ODMG Sprachanbindungen Programmierung einer Objektdatenbank: Sprachanbindungen für • C++ • Java • Smalltalk Deklarationen in ODL Deklarationen in ODL Precompiler Compiler Metadaten Object Code Linker Datenbankzugriff Ad hoc Anfragen Object Code Datenbankzugriff Objektbank ausführbares Programm ODMG2.0-19 IS-K2000 C++ OML Es gibt einige spezielle ODMG-Klassen für C++, die Datenzugriffe kapseln: • Objektpersistenz – Der new() Operator zum Instanziieren eines neuen Objekts, ist überladen, so dass auch eine Objektbank angegeben werden kann: d_Database * myDB = ...; d_Ref<Professor> prof = new(myDB) Professor; • Referenzierung – mit spezieller “Zeiger-Klasse” d_Ref<T>, die DB-Zugriffe verbirgt (s.o.) • Löschen – Persistente Objekte löscht man mit der Löschoperation von d_Ref: prof.delete_object(); • Objektmodifikation – Objektänderungen werden entweder direkt auf den Attributen, oder mittels Methoden (in C++ geschrieben) vorgenommen. Die Datenbankzugriffe geschehen intern mittels der d_Ref Klasse: prof->AHVNr = 4711; IS-K2000 ODMG2.0-20 10 aaa Java OML • Objektpersistenz – “persistence by reachability”: Jedes Objekt, auf das von einem persistenten Objekt verwiesen wird, wird automatisch vom System in der Objektbank gespeichert. – Es gibt keine Unterschiede in der Verwendung von transienten oder persistenten Java Objekte. • Referenzierung – Keine Besonderheiten gegenüber transienten Java-Objekten. • Löschen – Keine explizite Löschoperation für persistente Objekte vorgesehen stattdessen Garbage Collector auf Objektbank ausgedehnt • Objektmodifikation – Objektänderungen werden mittels Methoden, die ganz normal in Java geschrieben sind, vorgenommen. ODMG2.0-21 IS-K2000 Beispiel Java-Sprachanbindung import org.odmg.*; import odmg_example.*; Database db; Transaction trx; try { // Datenbankverbindung herstellen db = Database.current().open(“ODMG_Example”, Database.openReadWrite); trx= new Transaction(); trx.begin() // neues Professorenobjekt anlegen und persistent machen Professor eins = new Professor(“Einstein”, “123”, Professor.Assistent); db.bind( eins, “Einstein” ); // Objektmodifikationen eins.rang = Professor.Voll; eins.gehalt.erhöhen(10000, Gehalt.CHF); // Objekt löschen db.unbind(“Einstein”); // den Rest macht der Garbage Collector // Fortsetzung siehe nächste Folie ... IS-K2000 ODMG2.0-22 11 aaa Beispiel Java-Sprachanbindung (cont’d) // deklarative Anfragen BagOfObject profs = (BagOfObject) db.lookup(“Professoren”); Object hjs = profs.selectElement(“name=\”Schek\””); OQLQuery anfrage= new OQLQuery( “select v from v in Vorlesungen where v.dozent = $1”); anfrage.bind(hjs); BagOfObject result = (BagOfObject) anfrage.execute(); // do something useful with result Enumeration iter = result.createIterator(); while ( iter.hasMoreElements() ) { Vorlesung v = (Vorlesung) iter.nextElement(); System.out.println(v.titel); } trx.commit(); db.close(); } catch ( ODMGException exec ) { // error handling trx.abort(); throw exec; } ODMG2.0-23 IS-K2000 Syntax von Interface und Class - 1 <Interface> ::= <InterfaceHeader> ‘{’ [<InterfaceBody>] ‘}’ <InterfaceHeader> ::= ‘interface’ <Identifier> [<InheritanceSpec>] <Class> <ClassHeader> ::= <ClassHeader> ‘{’ <InterfaceBody> ‘}’ ::= ‘class’ <Identifier> [‘extends’ <ScopedName>] [<InheritanceSpec>] [<TypePropertyList>] <InheritanceSpec> ::= <TypePropertyList>::= <ExtentSpec> ::= <KeySpec> ::= <KeyList> ::= <Key> ::= <PropertyList> ::= | <PropertyName> ::= <ScopedName> ::= | IS-K2000 ‘:’ <ScopedName> [‘,’ <InheritanceSpec>] ‘(’ [<ExtentSpec>] [<KeySpec>] ‘)’ ‘extent’ <String> ‘key’[‘s’] <KeyList> <Key> | <Key> ‘,’ <KeyList> <PropertyName> | ‘(’ <PropertyList> ‘)’ <PropertyName> <PropertyName> ‘,’ <PropertyList> <Identifier> <Identifier> <ScopedName> ‘::’ <Identifier> ODMG2.0-24 12 aaa Syntax von Interface und Class - 2 <InterfaceBody> ::= <Export> | <Export> <InterfaceBody> <Export> ::= <TypeDecl> ‘;’ | <ConstantDecl> ‘;’ | <ExceptionDecl> ‘;’ | <AttributeDecl> ‘;’ | <RelationDecl> ‘;’ | <OperationDecl> ‘;’ <AttributeDecl> ::= [‘readonly’] ‘attribute’ <DomainType> <Ident.> <DomainType> ::= <SimpleType> | <StructuredType> | <EnumType> <RelationDecl> <TargetOfPath> <InversePath> ::= ‘relationship’ <TargetOfPath> <Identifier> ‘inverse’ <InversePath> ::= <Identifier> | <Collection> ‘<’ <Identifier> ‘>’ ::= <Identifier> ‘::’ <Identifier> <OperationDecl> <OpType> <ParameterList> <ParameterD> ::= ::= ::= ::= <OpType> <Identifier> ‘ (’ [<ParameterList>] ‘)’ <SimpleType> | ‘void’ <ParameterD> | <ParameterD> ‘,’ <ParameterList> [‘in’|‘out’|‘inout’] <SimpleType> <Identifier> ODMG2.0-25 IS-K2000 OQL Syntaxdiagramme - 1 ; define_query query_program define_query query define identifier as query Select Expression Basic Simple Expression Comparison query Boolean Expression Constructor Accessor Collection Expression Set Expression Conversion IS-K2000 ODMG2.0-26 13 aaa OQL Syntaxdiagramme - 2 * : identifier distinct Select Expression select query query as query identifier , from identifier query as , ODMG2.0-27 IS-K2000 OQL Syntaxdiagramme - 3 - identifier where query group by : query query query as identifier , having IS-K2000 query order by query asc desc ODMG2.0-28 14 aaa OQL Syntaxdiagramme - 4 Literals entry_name query_name Basic bind_argument from_variable_name ( ) query nil true false Literals Integer Float Character String ODMG2.0-29 IS-K2000 OQL Syntaxdiagramme - 5 + * Simple Expression query query / mod II - abs IS-K2000 ( query query ) ODMG2.0-30 15 aaa OQL Syntaxdiagramme - 6 Comparison comparison op query query like String and Boolean Expression query query or not = != > < >= <= Comparison Op ODMG2.0-31 IS-K2000 OQL Syntaxdiagramme - 7 query type_name ( ) type_name struct ( : identifier query ) , Constructors set bag ( ) query array , list list ( IS-K2000 ( query query , .. query query ) ) ODMG2.0-32 16 aaa OQL Syntaxdiagramme - 8 attribute_name . query relationship_name -> ( operation_name ) query , Accessor * query query query : query query first ( ) query last ( function_name ) query , ODMG2.0-33 IS-K2000 OQL Syntaxdiagramme - 9 count unique ( * ) exists sum Collection Expression ( min ) query max avg query query in some any comparison op all exists for IS-K2000 all identifier in query : query ODMG2.0-34 17 aaa OQL Syntaxdiagramme - 10 intersect Set Expression union query query except listtoset element Conversion distinct ( query ) flatten ( IS-K2000 class_name ) query ODMG2.0-35 18