Lehrstuhl für Praktische Informatik III Prof. Dr. Guido Moerkotte Email: [email protected] Pit Fender B6, 29, Raum C0.02 68131 Mannheim Telefon: (0621) 181–2517 Email: [email protected] Datenbanksysteme 2 Herbst-/Wintersemester 2011 1. Übungsblatt 28. September 2011 Aufgabe 1 In der Vorlesung wurden anhand einer ER-Modellierung von Polyedern die Nachteile relationaler Datenbanken diskutiert. Geben Sie ein ODL-Schema für das Polyeder-ER-Modell aus der Vorlesung an. Verwenden Sie das relationship-Konstrukt zur Realisierung der Beziehungen. Benutzen Sie den Datentyp float für die Koordinatenwerte. Die Polyeder sollen außerdem die Attribute Material (string) und Gewicht (float) haben. Geben Sie allen Klassen eine Extension. Wenn Sie mehrere Alternativen zur Realisierung der Beziehungen erkennen, diskutieren Sie jeweils Vor- und Nachteile. Lösung class Polyeder (extent AllePolyeder) { attribute float Gewicht; attribute string Material; relationship set<Flaechen> seiten inverse Flaechen::seiteVon; }; class Flaechen (extent AlleFlaechen) { relationship Polyeder seiteVon inverse Polyeder:: seiten ; relationship set<Kanten> kanten inverse Kanten::kanteVon; }; class Kanten (extent AlleKanten) { relationship set<Flaechen> kanteVon inverse Flaechen::kanten; relationship set<Punkte> verbindet inverse Punkte::kanten; }; class Punkte (extent AllePunkte) 1 { relationship set<Kanten> kanten inverse Kanten::verbindet; attribute float X; attribute float Y; attribute float Z; }; Aufgabe 2 In einem 3D-Zeichenprogramm soll eine photorealistische Darstellung von einigen der gespeicherten Objekte generiert werden. Dazu müssen zunächst für alle im Bildausschnitt vorkommenden Materialien die Texturen (Oberflächenbilder) geladen werden. Aufgabe 2 a) Gegeben sei das relationale Schema für die Polyeder aus der Vorlesung. Formulieren Sie die folgende Anfrage in SQL: Ermittle alle Materialien jener Polyeder, die Punkte mit ” X- und Y -Koordinaten zwischen 0 und 100 haben.“ Lösung select from where c.material polyeder c, flaechen f, kanten k, punkte p p.x between 0 and 100 and p.y between 0 and 100 and (k.P1=p.PunktID or k.P2=p.PunktID) and (k.F1=f.FlaechenID or k.F2=f.FlaechenID) and f.PolyID=c.PolyID Aufgabe 2 b) Formulieren Sie die Anfrage in OQL, mit dem ODL-Schema aus Aufgabe 1. Nutzen sie die relationships in Ihrem Schema aus, verwenden Sie z.B. möglichst einen Pfadausdruck! Lösung select from where f.seiteVon.material p in AllePunkte, k in p.kanten, f in k.kanteVon p.X>=0 and p.X<=100 and p.Y>=0 and p.Y<=100 oder select from where p.material p in AllePolyeder, f in p.seiten, k in f.kanten, v in k.verbindet v.X>=0 and v.X<=100 and v.Y>=0 and v.Y<=100 2 Aufgabe 3 Wie lässt sich die Objektidentität in einer objektorientierten Datenbank implementieren? Denken sie dabei insbesondere an den Objektidentifikator. Wie kann man sicherstellen, dass ein einmal vergebener Identifikator (OID) nicht wieder verwendet werden kann (dies muss während der gesamten Lebensdauer der Objektbank gelten)? Lösung Nach Kemper, Wimmer, Aufgabe 13.7 Prinzipiell gibt es zwei Ansätze: • physische OIDs und • logische OIDs. Die physische OID kodiert den Speicherort des identifizierten Objekts. Das geschieht über die ID des Speichermediums, der Seitenummer und Seitenposition. Die Seitenposition ist dann selbst ein Verweis auf den eigentlichen Speicherort innerhalb der Seite (slotted page). • Vorteil: Schneller Zugriff • Nachteil: Bei einer Datenbankreorganisation kann der Speicherort sich ändern (innerhalb der Seite wäre das kein Problem). In diesem Fall muss ein Platzhalter auf der Seite mit einer Referenz auf den neuen Speicherort eingefügt werden, damit die OID konstant bleibt. Dadurch entsteht eine weitere Indirektion (vgl. TID Konzept, overflow record). Des weiteren lässt sich die Wiederverwendbarkeit der OID nach erfolgter Löschung schwer verhindern. Logische OIDs referenzieren den Speicherort nur indirekt und unterstützen Datenbankreorganisationen und Löschoperationen von vornherein. Die Auflösung der OID erfolgt über eine Indirektion, bei welcher der aktuelle Speicherort des Objektes ermittelt wird. Dazu werden Indexstrukturen wie B-Bäume oder Hash-Tabellen verwendet. Ein weiteres Verfahren für logische OID wurde als direct mapping bekannt. Hier wird ein Objekt-Handle eingeführt, dessen Speicheradresse in der OID kodiert wird (somit ist die OID mit einer Art physischer OID für das Objekt-Handle vergleichbar). Das Handle selbst ist ein Zeiger, welcher die tatsächliche Position des Objektes speichert. Handles werden in dem sogenannten Handle Segment abgelegt, welches als (erweiterbares) Array implementiert ist. Im Detail besteht die OID aus einer System-ID, einer Seiten-ID, dem Slot auf der Seite und dem eindeutigen Abschnitt. Über die System-ID, Seiten-ID und dem Slot-ID wird somit das zuständige Handle im Handle Segment bestimmt. Der eindeutige Abschnitt ist nicht Teil der Referenz sondern verhindert eine Wiederverwendbarkeit der OID. Er ist im Wesentlichen ein Zähler, der Aktualisierungen in der Datenbasis unterstützt und ungültige Verweise (dangling references) von 3 gültigen zu unterscheiden hilft. Soll ein Handle wiederverwendet werden, wird dann einfach der Zähler inkrementiert, wodurch die Eindeutigkeit der OID gewährleistet wird. Aufgabe 4 Erstellen sie eine User Defined Function (UDF) in dem Datenbanksystem ihrer Wahl. Die Funktion hat einen Parameter vom Typ Character(32), der als Name einer Stadt dienen soll. Der Ausgabewert soll vom Typ Smallint sein. Die Funktion soll die aktuelle Temperatur der übergebenen Stadt ermitteln. Für die Ermittlung der Wetterdaten eignet sich die Google oder Yahoo Wetter API. Als Datenbanksystem empfiehlt sich die DB2 Express-Edition 9.7 (kostenlos). Implementieren sie die UDF in Java. Lösung import import import import COM.ibm.db2.app.UDF; java.io.IOException; java.io.InputStream; java.net.URL; import import import import javax.xml.parsers.DocumentBuilder; javax.xml.parsers.DocumentBuilderFactory; javax.xml.xpath.XPathExpressionException; javax.xml.xpath.XPathFactory; import org.w3c.dom.Document; public class DB2 UDF extends UDF { public void getTemperature(String inValue, short outValue) throws Exception { String result = ”−273”; try { URL url = new URL(”http://www.google.com/ig/api?weather=” + inValue); InputStream inputStream = url.openStream(); DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory .newInstance(); DocumentBuilder docBuilder = docBuilderFactory. newDocumentBuilder(); Document doc = docBuilder.parse(inputStream); inputStream.close(); result = XPathFactory .newInstance() .newXPath() 4 .evaluate( } } } } ”/xml api reply/weather/ current conditions/temp c/ @data”, doc); catch (javax.xml.parsers.ParserConfigurationException pce) { pce.printStackTrace(); catch (org.xml.sax.SAXException sa) { sa.printStackTrace(); catch (IOException ioe) { ioe .printStackTrace(); catch (XPathExpressionException xpe) { xpe.printStackTrace(); } set (2, Short.valueOf(result)) ; } } Add the following JAR-Files to your Build Path: • .../SQLLIB/java/db2jcc.jar • .../SQLLIB/java/db2jcc license cu.jar DROP FUNCTION get temperature; CREATE FUNCTION get temperature(character(32)) RETURNS SMALLINT LANGUAGE JAVA EXTERNAL NAME ’DB2 UDF!getTemperature’ PARAMETER STYLE DB2GENERAL EXTERNAL ACTION NOT DETERMINISTIC FENCED; COMMIT; SELECT get temperature(’Berlin’) from sysibm.sysdummy1; 5