490 likes | 605 Views
Hauptseminar Datenbanksysteme. - Datenbanken und XML - Thema: Type-Checking OQL Queries In The ODMG Type Systems. Angesprochene Punkte. Allgemeines zum Type Checking in Datenbanksystemen Kurze Einführung in den ODMG Standard Formale Definitionen und Regeln
E N D
Hauptseminar Datenbanksysteme - Datenbanken und XML - Thema: Type-Checking OQL Queries In The ODMG Type Systems
Angesprochene Punkte • Allgemeines zum Type Checking in Datenbanksystemen • Kurze Einführung in den ODMG Standard • Formale Definitionen und Regeln • Betrachtung von auftretenden Problemen und skizzieren von Lösungsvorschlägen • Referenzen
Type Checking (1/2) • Es gibt zwei Möglichkeiten von Type-Checking • Dynamisches type-checking während der Programmausführung • Statisches type-checking, zur Kompilierzeit
Type Checking (2/2) • Aus folgenden Gründen wird statisches type-checking bei Datenbanken bevorzugt: • Die Effizienz der Datenbank sollte nicht unnötig belastet werden • Laufzeitfehler sind bei Datenbanken besonders kritisch • „Message not understood“-Fehler werden durch statisches type-checking ausgeschlossen
ODMG Standard (1/5) • ODMG steht für Object Data Management Group (www.odmg.org) • 1993 wurde der ODMG 1.0 Standard veröffentlicht; der aktuelle Stand ist Release 3.0 • Dieser Vortrag geht noch auf den ODMG 2.0 Standard ein
ODMG Standard (2/5) Interface: Definiert das abstrakte Verhalten eines Objektes Class: Ist ein erweitertes Interface mit einem Status Literal: Definiert nur einen abstrakten Status
Was ist ein Interface? Ein Interface definiert das abstrakte Verhalten von Objekt-Typen. Ein Interface beinhaltet nur Methoden, keine Attribute. ODMG Standard (3/5) Beispiel (The top interface) interface Object { boolean same_as(in Object anObject); Object copy(); void delete(); };
Was ist eine Klasse? Eine Klasse ist ein erweitertes Interface. Eine Klasse definiert das abstrakte Verhalten und den abstrakten Zustand von Objekt-Typen. ODMG Standard (4/5) Beispiel (Class with extent) class Employee(extent employees) { attribute string name; attribute short id; attribute Department dept; float salary(); void hire(in Department d); void fire(); }; class Department(extent departments) { attribute string name; attribute short id; short NoOfEmployees(); };
Was ist ein Literal? Ein Literal definiert nur den abstrakten Zustand eines primitiven Literal-Typen. Es gibt keine Objektidentitäten für Literale ODMG Standard (5/5) • Literal-Typen: • boolean • char • short • long • float • double • octet • string • user-defined collection, • union and enumeration • literale
Das Resultat ist eine Menge vom Typ well_paid Der Typ well_paid ist vorher definiert und hat die Komponenten emp und sal Durch order by wird eine Liste von Objekten erzeugt OQL- Queries Beispiel select well_paid(emp: x.name, sal: x.salary()) from employees as x where x.salary() > 50000 and x.dept.NoOfEmployees()>100 order by emp
Collection Objects (1/2) • Es gibt verschiedene Typen von „Mengen“ • Set<t> : Eine Menge ohne Duplikate • Bag<t> : Eine Menge mit Duplikaten • List<t> : Geordnete Menge • Array<t> : Geordnete Menge mit Indizes • Dictionary<t,v> : Menge aus Schlüsseln denen ein Wert zugeordnet wird
Parametric polymorphism im ODMG Objektmodell any steht für jeden Objekttypen, dadurch ergeben sich auch weitere Probleme beim type-checking Die anderen Collection Types werden von diesem Interface abgeleitet Collection Objects (2/2) Interface Collection: Object { unsigned long cardinality(); boolean is_empty(); void insert_element(in any element); void remove_element(in any element); boolean contains_element(in any element); Iterator create_iterator(); };
Java unterstützt keinen parametrisierten Polymorphismus C++ bietet zu diesem Zweck Templates an Java vs. C++ interface Collection { int size(); boolean isEmpty(); void add(in Object element); boolean remove(in Object element); Iterator iterator(); ... }; interface Collection <T> { unsigned long cardinality(); boolean is_empty(); void insert_element(T element); void remove_element(T element); boolean contains_element(T element); Iterator <T> create_iterator(); };
Formale Spezifikation (1/2) • Ein Schema ist eine Menge von Verknüpfungen • Es beinhaltet Schlüsselwörter, die mit interfaces, classes, class extents und objects assoziiert sind • Ein Schema ist wohlgeformt, wenn: • jedes Schlüsselwort nur genau einer Zuordnung entspricht. • der Typ zu jedem Objekt ebenfalls im Schema enthalten ist. • bei interfaces und classes die Regeln für die Vererbung berücksichtigt wurden.
Formale Spezifikation (2/2) • Das Hinzufügen einer class extent zu einem Schema stellt ebenfalls den Namen des extent im Schema zur Verfügung. • Ein Schema beinhaltet vordefinierte Zuordnungen • String, int, boolean… • Collection, Bag, Set, List, Array… • die Datenbank-/Transaktionsklasse
Vererbung (1/5) • Das top interface ist „Object“, alle weiteren Interfaces werden von diesem abgeleitet
Reflexivität Transitivität Vererbung (2/5)
Substitution Ein Objekt vom Typ C2 kann ein Objekt vom Typ C1 ersetzen, falls C2 von C1 abgeleitet wird Die Regel beschreibt, daß im Ausdruck e ein vorkommendes y durch ein x ersetzt werden kann. Vererbung (3/5)
Vererbung (4/5) • Type casts • Ist ein Ausdruck e vom Typ C1 und es gilt außerdem noch, dass C2 von C1 abgeleitet ist, ist ein type-cast möglich • Es wird ein dynamisches type-checking benötigt
Vererbung (5/5) • Beispiel type casts class Person { (extent persons) ... } class Employee: Person { (extent employees) long salary(); ... } select well_paid(emp: x.name, sal:((Employee)x).salary()) from persons as x where ((Employee)x).salary() > 50000
Weitere Regeln zusammengefaßt • Auf ähnliche Weise können nun auch • Structures • Interfaces • Classes • Objects and Messages in das Schema mit aufgenommen werden.
OQL Queries and the ODMG object model (1/3) • Nun kommen wir zu dem ersten negativen Beispiel für das type-checking: select well_paid(emp: x.name, sal: x.salary()) from employees as x where x.salary() > 50000 • Employees ist vom Typ Collection • x ist ein Objekt vom Typ any
OQL Queries and the ODMG object model (2/3) • Methoden für den Type any sind im ODMG Standard nicht definiert • Es ist nicht möglich auf die Typkorrektheit von x.name und x.salary() zu schließen • Theorem: OQL-Queries können nicht auf Typkorrektheit überprüft werden.
OQL Queries and the ODMG object model (3/3) • Beweis: select projection from e1 as x1, e2 as x2, … ,en as xn where e • Die Variabel-Typen der xi müssen bestimmt werden • Die Variabel-Typen der ei müssen bestimmt werden • Im besten Fall nehmen wir an, daß die ei vom Typ Collection sind • Folglich sind die xi vom Typ any
OQL Queries and Java (1/5) • Die bisherigen Probleme beruhen auf dem Type any im ODMG Type-System • In der Java-Anbindung ist der Type Object das Wurzel-Objekt • Alle Objekte im Java-Typ-System erben die Eigenschaften des Wurzel-Objektes
OQL Queries and Java (2/5) • Theorem: Statisches Type-checking ist im Java-Type-System nicht möglich • Beweis • Der Typ der Variable x wird nun als Objekt identifiziert • Nur Methoden aus dem Interface „Object“ können benutzt werden • Das type-checking schlägt fehl sobald unbekannte Methoden aufgerufen werden
OQL Queries and Java (2/5) • Beispiel class Professor { public float salary() { } ... } class Course { public int enrollment() { } ... } Collection professors; Collection courses; select x from professors as x, x.courses() as y where x.salary() > 70000 and y.enrollment() > 50
OQL Queries and Java (3/5) • x.salary(), x.courses() und y.enrollment() werden stets als nicht typkorrekt klassifiziert • Hier stellt sich die Frage ob sich Java für die Datenbankprogrammierung eignet? • Betrachten wir zunächst eine Lösung für dieses Problem – dynamisches type-checking…
OQL Queries and Java (4/5) • OQL Query with type casts • Theorem: Bei ausdrücklicher Typangabe für jede Variabel innerhalb der Anfrag im Java-Typ-System ist ein type-checking möglich, allerdings nur auf Kosten des teuren Checks zur Laufzeit (ohne Beweis)
OQL Queries and Java (5/5) • Beispiel Collection professors; Collection courses; select x from professors as (Professor)x, x.courses() as (Course)y where x.salary() > 70000 and y.enrollment() > 50 • Diese Anfrage ist aufgrund des type-casts möglich • Es wird ein Check zur Laufzeit ausgeführt
OQL Queries and C++ (1/2) • Theorem: Ein Type-System, das parametrisierten Polymorphismus unterstützt erlaubt statisches type-checking von OQL Queries • Beweis: Dieses Resultat wird erziehlt, da zur Kompilierzeit jedem Collection-Type ein bestimmter Type zugeordnet wird. Dadurch wird jeder Element-Type eindeutig einer Menge zugeordnet. • Die Variablen einer Anfrage gehören einem spezifischen Types an
OQL Queries and C++ (2/2) • Beispiel in C++ Collection <Professor> professors; Collection <Course> courses; select x from professors as x, x.courses() as y where x.salary() > 70000 and y.enrollment > 50 • Korrolar: Das Type-System von C++ erlaubt statisches type-checking von OQL Queries
OQL Queries with Order by (1/2) • Eine Anfrage in allgemeiner Form: select projection from e1 as x1, e2 as x2, … ,en as xn where e order by e´1, e´2, … , e´m • Auch hier treten die schon bekannten Probleme auf • Ein Vergleich von zwei Objekten kommt hinzu
OQL Queries with Order by (2/2) • Theorem: Bei expliziter Typangabe für jede Variabel innerhalb der Anfrage mit Order by Klausel im Java-Typ-System ist ein type-checking möglich, allerdings wiederum nur zur Laufzeit • Theorem: Ein Type-System, das parametrisierten Polymorphismus unterstützt erlaubt statisches type-checking von OQL Queries mit Order by Klausel
Java OQL (1/6) • Java OQL ist eine Untersprach von Java und ermöglicht eine leichtere Anbindung an die Datenbank • Es gibt zwei Formen dieser Vereinfachung • durch Methoden • durch Klassen
Java OQL (2/6) • Zunächst die Möglichkeit durch Methoden interface DCollection extends java.util.Collection { Object selectElement(String predicate) java.util.Iterator select(String predicate) DCollection query(String predicate) boolean existsElement(String predicate) } • Die anderen Interfaces aus dem ODMG Standard (DSet, DBag, DList …) werden von diesem Interface abgeleitet
Java OQL (3/6) • Ein Java OQL Query DCollection bestPaid; bestPaid = employees.query( „for all x in employees: this.salary() >= x.salary()“ ); • Das obige Beispiel findet die Menge der bestbezahltesden Mitarbeiter
Java OQL (4/6) • Die Anfrage wird mittels eines Strings gestellt • Type-checking im Java-Type-System ist stets möglich, unabhängig vom Stringinhalt • Der String muß während der Laufzeit ausgewertet werden • Theorem: Das type-system von Java kann mit Java-OQL-Queries nicht umgehen, so daß ein type-checking nicht möglich ist
Java OQL (5/6) • Java OQL Queries als Klassen class OQLQuery { // Java constructors OQLQuery create(String query); void bind(Object parameter); Object execute(); } DBag selectedEmployee; OQLQuery query = new OQLQuery(); query.create(„select well_paid(emp: x.name, sal: x.salary()) from employees as x where x.salary() > $1 and x.dept.NoOfEmployees() > $2“); query.bind(50000); query.bind(100); selectedEmployees = (DBag) query.execute();
Java OQL (6/6) • Es werden gut bezahlte Mitarbeiter in großen Abteilungen gesucht • Bei diesem Beispiel treten mehrere Probleme auf: • Es kann nur ein Laufzeitcheck ausgeführt werden • Die Übergabeparameter (mittels query.bind()) müssen zu dem Query passen • Der Rückgabewert von query.execute() ist Object, die Select-Anweisung liefert eine Menge von Objekten
C++ und OQL-Erweiterung • Auch für C++ gibt es eine Erweiterung für die vereinfachte Anbindung an die Datenbank • Die in C++ zur Verfügung stehenden Templates helfen hier auch nicht • Die Queries werden als String gegeben… • Beim type-checking sind Strings stets typkorrekt • C++ unterliegt den selben Problemen, die eben im Java-Typ-System diskutiert wurden
Geordnete Mengen (1/2) • Weder im ODMG-Standard noch im Java oder C++ Type-System können geordnete Menge auf Typkorrektheit geprüft werden • Ein Beispiel im ODMG Object Model interface Ordered_Collection: Collection { unsigned long cardinality(); boolean is_empty(); void insert_element(in Ordered element); void remove_element(in Ordered element); boolean contains_element(in Ordered element); Iterator create_iterator(); }
Geordnete Mengen (2/2) • Das Interface Ordered_Collection erbt von Collection • Die Vererbungsregeln wurden bei den folgenden Funktionen nicht befolgt • insert_element • remove_element • contains_element • Die Funktionsköpfe (die Aufrufparameter) dieser Funktionen wurden geändert
Bounded Type Quantification • Theorem: Ein Type-System, das bounded type quantificatien unterstützt und das top-Object beinhaltet kann geordnete Mengen auf Typkorrektheit überprüfen interface Ordered_Collection <T: Ordered>: Collection <T>{ ... } • Eiffel unterstützt diese Methode, doch C++ benötigt eine klare Vererbungsstruktur
F-Bounded polymorphism (1/3) • Theorem: Wenn die C++-Anbindung an die Datenbank F-bounded polymorphism unterstützt ist ein statisches type-checking von Queries möglich interface Ordered_Collection <T: Ord_element <T>> :Collection <T>{ ... }
F-Bounded polymorphism (2/3) • Beispiel interface Employee { String name; short id: //boolean leq(Employee e); } • Dieses Interface entspricht nicht den Vererbungsregeln, da Employee nicht von Ord_element <Employee> abgeleitet wird
F-Bounded polymorphism (3/3) • Durch das obige Interface werden die Vererbungsstrukturen wiederhergestellt • Es wird garantiert, daß die Methoden die richtige Signatur haben • Statisches Type-checking ist möglich interface Ord_element <Employee> { boolean leq(Employee e); }
Zusammenfassung • OQL Queries können im ODMG-Standard nicht auf Korrektheit geprüft werden • OQL Queries können in der Java-Anbindung nicht auf Korrektheit überprüft werden • Parameter Polymorphismus sollte von einer Sprache für die Datenbank unterstüzt werden • Um geordnete Menge korrekt zu überprüfen wird F-bounded polymorphism benötigt
Referenzen • Type-Checking OQL Queries In The ODMG Type System Suad Alagic – Wichita State University ACM Transaction on Database Systems, Vol.24, No. 3 September 1999, Page 319-360 • The Object Data Standard ODMG 3.0 R.G.G. Cattell, Douglas Barry, Mark Berler, Jeff Eastman, David Jordan, Craig Russell, Olaf Schadow, Torsten Stanieda Fernando Velez Verlag: Morgan Kaufmann Publishers ISBN: 1-55860-647-5