Einführung in Datenbanksysteme, Datenbanken für die Bioinformatik Sommersemester 2009 4. Übungszettel (Musterlösung) Einführung in Datenbanksysteme Datenbanken für die Bioinformatik Heinz Schweppe, Jürgen Broß, Katharina Hahn Hinweise: ● ● ● Auf dem Server esel verfügbar, wird die TerraDB sowohl für Oracle als auch für Postgres zur Verfügung gestellt. Auf der Veranstaltungswebseite sind Informationen verfügbar, wie Sie auf die jeweilige Datenbank zugreifen können. Logins für die Übungsaufgaben erhalten Sie in Ihren Tutorien. Zusatzpunkte werden auf dem aktuellen Zettel verrechnet. Aufgabe 1 (Relationale Algebra) 9 Punkte Gegeben sei folgendes Datenbankschema, in dem Informationen über Orte, Filme und das aktuelle Programm gespeichert sind: KinoDB ( Orte(Kino, Adresse, Telefon), Filme(Titel, Regie, Schauspieler), Programm(Kino, Titel, Zeit) ) Beachten Sie, dass der Primärschlüssel den Relationen Filme und Programm jeweils alle drei Attribute umfasst, da ein Film von mehreren Regisseuren gedreht worden sein kann (z.B. Raumpatrouille Orion - Rücksturz ins Kino) und mehrere Schauspieler mitspielen können, bzw. ein Film an einem Ort zu verschiedenen Uhrzeiten gezeigt werden kann. a) Interpretieren Sie folgende Ausdrücke der relationalen Algebra in natürlicher Sprache: (1) Regisseur Schauspieler =Scarlett Johansson Filme Welche Regisseure haben schon mal mit Scarlett Johansson gearbeitet? (2) Schauspieler Filme ⋈ Titel =Titel Programm Welche Schauspieler spielen in Filmen, die aktuell laufen? (3) Kino , Adresse Orte ⋈ Kino=Titel Titel Schauspieler=Humphrey Bogart Filme∖ Titel Programm Welche Kinos (+Adresse) sind nach einem Film mit Humphey Bogart benannt, der nicht mehr aktuell in den Kinos läuft? (Casablanca) b) Geben Sie folgende Anfragen in relationaler Algebra an: Ausgabe 07.05.2008 Einführung in Datenbanksysteme, Datenbanken für die Bioinformatik Sommersemester 2009 (1) In welchen Filmen (Titel) spielt Philip Seymour Hoffman mit? Titel sigmal Schauspieler=Philipp Seymour Hoffman Filme (2) In welchen Kinos (Name und Adresse) laufen Filme mit Natalie Portman? Kino , Adresse Orte ⋈ Kino=Kino Programm ⋈ Titel =Titel Schauspieler= Natalie Portman Filme (3) Welche Regisseure haben noch nie mit Nicolas Cage gearbeitet? Regisseur Filme∖ Regisseur Schauspieler=Nicolas Cage Filme (4) In welchen laufenden Filme spielen ausschließlich Schauspieler mit, die schon mal mit Steven Spielberg gearbeitet haben? Titel Programm∖ Titel Filme ⋈ Schauspieler =Schauspieler Schauspieler Filme∖ Schauspieler Regisseur =Stephen Spielberg Filme Man selektiert alle Schauspieler, die schon mal mit Spielberg gearbeitet haben, zieht diese von allen ab und erhält somit alle Schauspieler, die noch nie mit Steven Spielberg gearbeitet haben. Dann selektiert man alle Filme, mit einem solchen Schauspieler und zieht diese Menge von der Menge aller aktuelle laufenden Filme ab. Aufgabe 2 (SQL Anfragen) 10 (+2) Punkte Gegeben sei das Datenbankenschema aus Aufgabe 1. Formulieren Sie folgende Anfragen in SQL. a) In welchen Kinos (Name und Adresse) läuft Slumdog Millionaire? SELECT o.Kino, o.Adresse FROM Orte o, Programm p WHERE o.Kino = p.Kino AND p.Titel = 'Slumdog Millionaire' b) Welche Filme laufen nicht mehr aktuell im Kino? SELECT Titel FROM Filme f WHERE f.Titel NOT IN (SELECT Titel FROM Programm p) c) In welchen Kinos (Name und Adresse) laufen Filme mit Johnny Depp? SELECT o.Name, o.Adresse FROM Orte o, Programm p, Filme f WHERE o.Kino = p.Kino AND p.Titel = f.Titel AND f.Schauspieler = 'Johnny Depp' d) Welcher Regisseur hat schon mal mit Romy Schneider und James Dean gearbeitet? Beachten Sie, dass die Zusammenarbeit mit den beiden genannten Schauspielern in unterschiedlichen Filmen stattgefunden haben kann. SELECT f1.regie FROM Filme f1, Filme f2 WHERE f1.regie = f2.regie AND f1.Schauspieler = 'Romy Schneider' AND f2.Schauspieler = 'James Dean' e) Wieviele Filme laufen aktuell, bei denen Andreas Dresen Regie geführt hat? SELECT COUNT (f1.regie) FROM Filme f, Programm p WHERE f.Titel = p.Titel AND f.Regie = 'Andreas Dresen' Zusatzaufgabe: f) In welchen laufenden Filmen spielen ausschließlich Schauspieler mit, die schon mal mit Steven Spielberg gearbeitet haben? SELECT Titel FROM Programm p WHERE p.titel NOT IN (SELECT f3.Titel FROM Filme f3 Ausgabe 07.05.2008 Einführung in Datenbanksysteme, Datenbanken für die Bioinformatik Sommersemester 2009 WHERE Schauspieler IN --alle schauspieler, die noch nicht mit spielberg gearbeitet haben (SELECT DISTINCT Schauspieler FROM Filme f2 WHERE schauspieler NOT IN (SELECT Schauspieler FROM Filme f WHERE f.Regie='Steven Spielberg'))) Geben sie jeweils gültige SQL-Statements an. Aufgabe 3 (SQL - TerraDB) 12 (+3) Punkte Die TerraDB steht Ihnen auf dem Server esel zur Verfügung. Auf der Webseite finden Sie Informationen, wie Sie mit Hilfe Ihres Logins auf die Datenbank zugreifen können. Formulieren Sie die folgenden Anfragen in SQL. Verwenden Sie für ihre Anfragen jeweils die englische Version der TerraDB (unter Oracle terradb_english, unter Postgres geodb). Einige der Anfragen lassen sich unter zu Hilfenahme der Mengenquantoren ALL, ANY, EXISTS formulieren. Beachten Sie die Hinweise (s.u.): a) Finden Sie alle Landesteile, durch die der Mekong fließt. Geben Sie sowohl die Landesteil und das jeweilige Land namentlich an. SELECT DISTINCT l.name as Land, t.name as Landesteil FROM terradb.land l, terradb.landesteil t, terradb.geo_fluss f WHERE t.L_ID = f.L_ID AND t.LT_ID = f.LT_ID AND t.L_ID = l.L_ID AND f.fluss = 'Mekong' ORDER BY l.name, t.name; b) Welche Länder liegen nicht an Meeren, wohl aber alle ihre Nachbarländer? Geben Sie die Länder namentlich an. WITH ohne_kueste AS (SELECT l.l_id AS ok_id, l.name AS ok_name FROM terradb.land l WHERE l.l_id NOT IN (SELECT l_id FROM terradb.geo_meer)), nachbarlaender AS (SELECT l.l_id AS nb_id, b.land2 AS nb_id2 FROM terradb.land l, terradb.benachbart_sym b WHERE l.l_id = b.land1 AND l.l_id NOT IN (SELECT l_id FROM terradb.geo_meer)) SELECT DISTINCT ok_name FROM ohne_kueste WHERE NOT EXISTS (SELECT * FROM nachbarlaender WHERE nachbarlaender.nb_id2 = ohne_kueste.ok_id) order by ok_name; ohne_kueste enthält die Länder, an die laut geo_meer, kein Meer grenzt. In nachbarlaender, sind Länder (ohne Küste) mit samt ihren Nachbarn drin (für jedes Paar ein Tupel). Man selektiert jetzt alle Länder aus ohne_kueste, die selbst nicht Nachbar zu einem Land ohne Kueste (keinen Eintrag unter nb in nachbarn) sind. Denn ein Land L, das keine Küste hat selbst Nachbar zu einem Land L2 ist, das keine Küste hat, dann kann es nicht selektiert werden, weil L2 auch keine Küste hat, somit nicht den Suchkriterien entspricht. alternative Lsg fuer Postgres : SELECT country2, country.name , count(country1) FROM country LEFT JOIN neighbor_of_sym ON (country2 = country.c_id AND country1 NOT IN (SELECT distinct country.c_id FROM geo_sea NATURAL JOIN region JOIN country ON (country.c_id = region.c_id))) WHERE country.c_id NOT IN (SELECT distinct country.c_id FROM geo_sea natural JOIN region JOIN country ON (country.c_id = region.c_id)) GROUP BY country2, country.name HAVING count(country1) = 0; Ausgabe 07.05.2008 Einführung in Datenbanksysteme, Datenbanken für die Bioinformatik Sommersemester 2009 c) Welche Länder (Name) mit mehr als 10 Millionen Einwohnern haben eine höhere Bevölkerungsdichte (Einwohner/Landfläche) als alle ihre Nachbarländer? SELECT l.name, l.population, l.population/l.area AS density FROM country l WHERE l.population > 10000000 AND l.population/l.area > ALL (SELECT l2.population/l2.area FROM country l2, neighbor_of_sym b WHERE b.country1 = l.c_id AND b.country2 = l2.c_id) d) Finden Sie alle Länder, die direkt an Sambia grenzen. ); SELECT l2.name FROM terradb.Land l1,terradb.Land l2,terradb.benachbart b WHERE l1.name='Sambia' AND((b.Land1=l1.L_ID AND b.Land2=l2.L_ID) OR( b.Land2=l1.L_ID AND b.Land1=l2.L_ID)) oder SELECT l2.name FROM Terradb.Land l1,Terradb.Land l2,Terradb.benachbart_sym b WHERE l1.name='Sambia' AND b.Land1=l1.L_ID AND b.Land2=l2.L_ID e) Geben Sie alle Flüsse an, die in ein Meer münden. Das Meer soll dabei nur an eines der Landesteile grenzen, durch das der Fluss fließt. Das Meer kann aber an andere Landesteile grenzen, durch die der Fluss nicht fließt. SELECT r.name FROM river r, geo_river gr, geo_sea gs WHERE r.sea <> '' AND r.name = gr.river AND gr.r_id = gs.r_id AND gr.c_id = gs.c_id AND r.sea = gs.sea GROUP BY r.name HAVING COUNT (gs.sea)=1 ORDER BY r.name; Zusatzaufgabe f) Gesucht sind die Meere (Name), die die maximalen Anzahl an anliegenden Städten mit mehr als 1 Mio. Einwohner haben bzw. mit der maximalen Anzahl der Flüsse, die in sie münden. SELECT s.name FROM sea s WHERE s.name IN ( SELECT a.sea FROM ( SELECT l.sea, count(*) AS count1 FROM located_at l, city c WHERE c.c_id = l.c_id AND c.r_id = l.r_id AND l.city = c.name AND c.population > 1000000 AND l.sea IS NOT NULL GROUP BY l.sea ORDER BY count1 DESC LIMIT 1) AS a ) OR s.name IN ( SELECT b.sea FROM ( SELECT r.sea, count(*) AS count2 FROM river r WHERE r.sea IS NOT NULL GROUP BY r.sea ORDER BY count2 DESC LIMIT 1) AS b ) Geben sie jeweils gültige SQL-Statements an. Hinweise: Die Informationen in der TerraDB sind nicht vollständig, daher kann es vereinzelt zu irreführenden Ergebnissen kommen. Z.B. sind keine Informationen darüber gespeichert, an welchen Meer(en) Thailand oder die Fidschi-Inseln liegen. Ausgabe 07.05.2008 Einführung in Datenbanksysteme, Datenbanken für die Bioinformatik Sommersemester 2009 Die Relation, neighbor_of ist nicht symmetrisch. Eine symmetrische Darstellung der Nachbarschaftsbeziehung bietet die View 'neighbor_of_sym'. Diese ermöglicht einfachere SQL-Statements bei der Formulierung mancher Anfragen. Aufgabe 4 (Kardinalitäten von Join-Ergebnissen) 8 Punkte Gegeben seien die Relationen R, S, T mit den Attributen r1, r2, … bzw. s1, s2, … bzw. t1, t2, … und den Kardinalitäten |R|, |S| und |T|. Die Relation Q bezeichnet das Ergebnis des Inner-Joins von R, S und T wie folgt: Q=R ⋈ ri=sj S ⋈ sk=tl T a) Zwischen welchen Schranken liegt die Kardinalität von Q? ∀ i , j :r i≠s j ) und S keinen Joinpartner in T findet (also für alle Tupel in R und S gilt: ∀ k , l :s k ≠t l ), dann ist die Kardinalität von |Q| = 0. Falls im Gegensatz dazu folgendes gilt ∀ i , j :r i=s j und ∀ k , l :s k =t l , dann ist die Kardinalität von Q: |Q| = |R| * |S| * |T|. Daher gilt: Falls R keinen Joinpartner in S findet (für alle Tupel in R und S gilt: 0 <= |Q| <= |R| * |S| * |T| b) Zwischen welchen Schranken liegt die Kardinalität von Q, falls ri Schlüssel von R ist? Falls keine Joinpartner gefunden werden, ist |Q| = 0. Da ri der Schlüssel von R ist, müssen die Werte paarweise verschieden sein. Somit ist die Obergrenze von |Q| = |S|. Es gilt also: 0 <= |Q| <= |S| * |T| c) Zwischen welchen Schranken liegt die Kardinalität von Q, falls ri Schlüssel von R und tl Schlüssel von T ist. Falls keine Joinpartner gefunden werden, ist |Q| = 0. Für den ersten Teil des Joins gilt die Kardinalität wie eben erläutert. Da tl Schlüssel von T ist, müssen die Werte von tl paarweise verschieden sein. Daher gilt: 0 <= |Q| <= |S| d) Zwischen welchen Schranken liegt die Kardinalität von Q, falls ri Schlüssel von R, sj ein Fremdschlüssel auf R ist und tl Schlüssel von T ist. Die obere Schranke ändert sich gegenüber c) nicht. Da sj Fremdschlüssel auf R ist, kann sj entweder nur den Wert NULL annehmen, oder eindeutige Werte aus R. Wenn alle sj NULL sind, dann ist der linke Teil des Joins leer. Daher gelten die gleichen Kardinalitäten, wie bei c). (Begründung für die untere Schranke muss gegeben werden). Geben Sie möglichst scharfe Schranken an und erläutern Sie Ihre Antwort. Ausgabe 07.05.2008