07.03.2014 Aufrufe

Datenbanken I 2. Relationale DB - Technologie der ...

Datenbanken I 2. Relationale DB - Technologie der ...

Datenbanken I 2. Relationale DB - Technologie der ...

MEHR ANZEIGEN
WENIGER ANZEIGEN

Erfolgreiche ePaper selbst erstellen

Machen Sie aus Ihren PDF Publikationen ein blätterbares Flipbook mit unserer einzigartigen Google optimierten e-Paper Software.

Prof. Dr. rer.nat.habil. Bernhard Thalheim<br />

Information Systems Engineering<br />

Institute of Computer Science and Applied Mathematics<br />

Christian-Albrechts-University Kiel<br />

Olshausenstr. 40<br />

D - 24098 Kiel<br />

<br />

[];a,,<br />

Vorlesung <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> SS 2008<br />

2 <strong>Relationale</strong> <strong>Datenbanken</strong><br />

Paradigmen<br />

formale Sprache \ Theorie Abstraktion Entwurf<br />

erfinden • •<br />

verwirklichen<br />

•<br />

benutzen<br />

•<br />

<strong>2.</strong>1 Das relationale Modell<br />

<strong>2.</strong>1.1 Informale Einführung<br />

Spezialfall des (nachfolgenden (Kapitel 3)) Entity-Relationship-Modelles:<br />

keine Relationship-Typen<br />

damit gelten spezifische Einschränkungen:<br />

keine expliziten rekursiven Typen<br />

Sichten ohne rekursive Definition<br />

Vorteil: nur ein Typenkonstruktur ⇒ einfache Theorie, einfache Operationen, einfache Systeme, Optimierung<br />

Dafür:<br />

umfangreiche Theorie <strong>der</strong> Integritätsbedingungen<br />

funktionale Abhängigkeiten X −→ Y<br />

Gültigkeit von funktionalen Abhängigkeiten<br />

mehrwertige Abhängigkeiten X → Y<br />

Verbundabhängigkeiten (X 1 , ...X m )<br />

Inklusionsabhängigkeiten R[X] ⊆ S[Y ]<br />

Relationenschema R = (R, X, Σ) über Datenschema BT<br />

primärer Schlüssel X o<strong>der</strong> Menge von Schlüsseln K<br />

Integritätsbedingungen Σ<br />

Σ ⊆ L R<br />

für die logische Sprache L R über R<br />

es werden dem Relationenschema Basis-Datentypen unterlegt<br />

deshalb besser Basis-Datentypen BT mit Elementen DT (D) = (domain(D), Ops(D), P red(D)<br />

und Assoziationsschema zum Namensraum dom : U → BT<br />

Instanz (Ausprägung) [Klasse] als zeitverän<strong>der</strong>liche Menge von Elementen<br />

SAT (R)


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 2<br />

Modell im Sinne <strong>der</strong> Modelltheorie <strong>der</strong> mathematischen Logik<br />

aufgrund <strong>der</strong> Mengendefinition: Jede Relation hat mindestens einen Schlüssel: R<br />

Wir sprechen hier von Schlüsseln und minimalen Schlüsseln<br />

in an<strong>der</strong>en Bücher oft Superschlüssel und Schlüssel verwandt<br />

mitunter auch Schlüsselkandidat<br />

ein Schlüssel wird ausgezeichnet zur Hauptidentifikation<br />

außerdem: kürzeste Schlüssel bzgl. <strong>der</strong> Anzahl <strong>der</strong> Attribute<br />

meist wird angenommen: Schlüssel nicht leer<br />

ansonsten nur einelementige Klassen betrachtet<br />

Implementationsentscheidung: Primärschlüssel-Werte sind stets vollständig definiert<br />

wird bei den meisten Systemen gefor<strong>der</strong>t und demzufolge auch in <strong>der</strong> Literatur<br />

<strong>Relationale</strong>s Datenbankschema <strong>DB</strong> = (R 1 , ..., R n , Φ)<br />

Instanz (Datenbank)<br />

mit dem Assosiationsschemata dom Ri : R i → BT<br />

sowie einer Erklärung <strong>der</strong> Bedeutung <strong>der</strong> einzelnen Attribute und Relationenschemata<br />

Dynamisches Relationenschema Dyn R = (R, Dyn Σ)<br />

über R = (R, X, Σ) über Datenschema BT<br />

Dynamische Integritätsbedingungen Dyn Σ über ListSAT ((R))<br />

Dynamisches relationales Datenbankschema <strong>DB</strong> = ( Dyn R 1 , ..., Dyn R n , Dyn Φ)<br />

db - Instanz eines relationalen Datenbankschemas<br />

Dyn db - Liste von Instanzen eines relationalen Datenbanksschemas, in <strong>der</strong> Dyn Φ gilt<br />

Klassifikation <strong>der</strong> Integritätsbedingungen<br />

Statische Integritätsbedingungen für eine Datenbank o<strong>der</strong> eine Klasse meist als implikative Formeln o<strong>der</strong> auch<br />

Hornformeln<br />

Gleichungspostulate, die aus <strong>der</strong> Gültigkeit von (Un-)Gleichungen die (Un-)Gültigkeit von weiteren Gleichungen<br />

folgt, insbeson<strong>der</strong>e<br />

• funktionale Abhängigkeiten<br />

insbeson<strong>der</strong>e Schlüsselbeziehungen<br />

Existenzpostulate, die aus <strong>der</strong> Existenz von Objekten die Existenz von an<strong>der</strong>en Objekten for<strong>der</strong>n, insbeson<strong>der</strong>e<br />

• Inklusionsabhängigkeiten<br />

• Exklusionsabhängigkeiten<br />

• mehrwertige, hierarchische und Verbundabhängigkeiten<br />

Anzahlbeschränkungen, die eine Minimal-/Maximalanzahl von Objekten in Klassen o<strong>der</strong> <strong>Datenbanken</strong><br />

angeben (formulierbar oft als Gleichungspostulate)<br />

Dynamische Integritätsbedingungen für Listen von <strong>Datenbanken</strong> bzw. Klassen<br />

Transitionsabhängigkeiten, die aufeinan<strong>der</strong>folgende Elemente einer Liste beschränken<br />

temporale Formeln, mit denen für Listen die Gültigkeit eines Zustandes für ein Element <strong>der</strong> Liste postuliert<br />

wird<br />

Instanz ist eine Liste von Klassen, in <strong>der</strong> Dyn Σ gilt


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 3<br />

Update-Operationen<br />

• Insert - Einfügen eines Elementes in eine Menge<br />

• Delete - Streichen eines Elementes aus einer Menge nach entsprechen<strong>der</strong> Identifikation<br />

• Update - Verän<strong>der</strong>n von Attributwerten nach vorgegebener Spezifikation (single-tuple o<strong>der</strong> multiple-tuple -<br />

je nach Spezifikation)<br />

Zusätzliche Annahme: Unique-name-assumption<br />

Attribute mit den gleichen Namen meinen Gleiches.<br />

Zusammenhang wird über Inklusionsbeziehung modelliert<br />

<strong>2.</strong>1.2 Implizite Annahmen <strong>der</strong> Spezifikationssprache<br />

Harmonisierte Assoziationen zu Basis-Datentypen d.h. falls dom Ri (A) und dom Rj (A) beide definiert sind,<br />

dann sind sie gleich<br />

dann kann auch dom als eine Funktion geführt werden<br />

kann ausgebaut werden zur unique name assumption: noch Attribute mit gleicher Bedeutung tragen gleichen<br />

‘Namen’<br />

kann noch weiter ausgebaut werden zur unique flavour assumption:<br />

nur Attribute mit gleichem Namen können durch (Un)Gleichungsanfragen verbunden werden<br />

bei allen an<strong>der</strong>en Attributen ist dies wenig sinnvoll<br />

für disziplinierte Entwicklung durch aus sinnvoll<br />

Primary key assumption: alle Werte zum Primärschlüssel sind definiert<br />

weiterhin: Alle Objekte sind identifizierbar<br />

Mengensemantik für alle Klassen, alle Komponenten (z.B. Attribute, Relationennamen)<br />

in SQL-<strong>Datenbanken</strong> allerdings: Multimengen-Semantik<br />

Endlichkeitsannahme: alle Klassen sind endlich, eine Datenbank besteht aus endlich vielen Klassen<br />

<strong>2.</strong>1.3 Tabellendarstellung von Relationen<br />

Darstellung <strong>der</strong> Daten in Tabellenform<br />

• Tabelle beschreibt einen Entity-Typen<br />

Klassen werden in Tabellen dargestellt<br />

• Spalte entspricht einem Attribut<br />

Spaltennamen - Relationenschema<br />

• Zeile stellt ein Objekt dar<br />

Vorsicht: Tabelle kann auch wie<strong>der</strong>holende Einträge besitzen<br />

Relation nicht (ist eine Menge)<br />

Reihenfolge <strong>der</strong> Zeilen und Spalten unwesentlich wegen eindeutiger Identifikation<br />

• Attribute durch Attributnamen<br />

• Zeilen durch ihre Werte auf allen Attributen o<strong>der</strong> einem Teil <strong>der</strong> Attribute


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 4<br />

Damit kann in Tabellenform <strong>der</strong> Inhalt dargestellt werden :<br />

STUDENT<br />

PNum SNum Hauptf Nebenf Betreuer<br />

...<br />

VORLESUNG<br />

Kurs Raum Zeit Semester Lesen<strong>der</strong><br />

.... ... ... .... ....<br />

VORLESUNG stellt bereits eine Beziehung dar<br />

damit ist auch eine komplexere Integritätsbeschränkung verbunden: z.B. muß <strong>der</strong> Kursname legitim sein<br />

Relationenname, Attributnamen, Schlüssel<br />

<strong>2.</strong>1.4 Einschub: Probleme des relationalen Modelles<br />

Darstellung einer Beziehung von Objekten<br />

(Relationenmodell unterscheidet nicht zwischen Objekt und Beziehung)<br />

• als eigenes Relationenschema<br />

• als Teil eines Relationenschemas, das mehrere Relationenschemata verknüpft<br />

Problem:<br />

• Redundanz<br />

• Konsistenz<br />

• Verluste (Anomalien)<br />

Lösung: Normalformen<br />

• unique-name-assumption<br />

gleiche Namen bedeuten das Gleiche<br />

Anmerkung zur Normalisierung: an<strong>der</strong>e Formen neben <strong>der</strong> vertikalen (attributbasierten) Normalisierung sind<br />

• horizontale Normalisierung<br />

• deduktive Normalisierung<br />

Probleme mit nichtnormalisierten Schemata<br />

VORLESUNGSBESUCH<br />

Kurs Raum Zeit Semester Lesen<strong>der</strong> Student Note<br />

.... ... ... .... .... ... ...<br />

Eine Verlegung einer Vorlesung in einen an<strong>der</strong>en Raum bedingt eine umfangreiche Än<strong>der</strong>ung in <strong>der</strong> Tabelle (nicht<br />

nur die Än<strong>der</strong>ung eines Datums);<br />

Löschen einer Note des letzten Studenten läßt letzten Hinweis auf Vorlesung verschwinden;<br />

ein Eintrag einer neuen Vorlesung ist erst mit <strong>der</strong> Belegung von Studenten möglich<br />

damit ist die Tabelle nicht in <strong>der</strong> geeigneten Form<br />

Lösung : Normalisierung (s. Kapitel 3)


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 5<br />

<strong>2.</strong>1.5 Darstellung durch Hypergraphen<br />

<strong>Relationale</strong>s Datenbankschema läßt sich durch Hypergraphen darstellen.<br />

Damit: Querying Hypergraphen<br />

Beispiel aus dem Unibeispiel<br />

Bestimme für den Studenten “Alf Brummkopf” den Fachbereich seines Hauptfaches.<br />

Relationen:<br />

• Person = ({Name.First, Name.Fam, Name.Titel, Addr...., Personennummer} ,<br />

{ Personennummer}, ∅)<br />

• Student = ( { StudNr, Person.Personennummer, Hauptfach.Fachber.DName }, {StudNr},<br />

{ { Personennummer } −→ { StudNr } } )<br />

• sonstige Semantik: Student[Person.Personennummer] ⊆ Person[Personennummer] ...<br />

Damit kann dann die Anfrage im Hypergraphen direkt dargestellt werden.<br />

PERSON<br />

Name<br />

Adresse<br />

PNum<br />

Spezialis<br />

PROFESSOR<br />

SNum<br />

Hauptf<br />

Nebenf<br />

Betreuer<br />

STUDENT<br />

Kurs<br />

Semester<br />

Note<br />

TEILNAHME<br />

Zeit<br />

Raum<br />

VORLES<br />

Darstellung erfolgt nach Einführung <strong>der</strong> Algebra.<br />

<strong>2.</strong>1.6 Die unterlegten Datentypen<br />

Datentypen sind gegeben durch<br />

• Wertebereich,<br />

• Operationen mit entsprechenden Axiomen,<br />

• Prädikate mit entsprechenden Axiomen.<br />

Daraus sind insbeson<strong>der</strong>e die folgenden Eigenschaften für die Benutzung in <strong>Datenbanken</strong> von Relevanz:<br />

Präzision und Genauigkeit und daraus resultierende Eigenschaften von Operationen


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 6<br />

Granularität<br />

Ordnungsrelationen zur Anordnung von Werten mit unterschiedlichen Ordnungschemata<br />

Klassifikation (linear, hierarchisch, ...; eindimensional, mehrdimensional; polydimensional; analytisch/synthetisch;<br />

mono-/polythetisch)<br />

Speicherformate ggf. mit Auswahl<br />

Präsentationsformate ggf. mit Verkürzunsregeln<br />

Default-Werte mit spezifischer Bedeutung<br />

Rundungsregeln zur Anpassung von / an Werte an<strong>der</strong>er Typen<br />

Maßeinheiten mit ggf. Umwandlungsregeln<br />

Aggregationsoptionen<br />

Ggf. wird mit <strong>der</strong> Assoziation eines Datentypen mit einem Attribut eine Verfeinerung vorgenommen.<br />

Außerdem können Nullwerte zugelassen sein, assoziierbar sein o<strong>der</strong> auch verboten sein.<br />

Funktionen besitzen an den “Randpunkten” i.a. an<strong>der</strong>es Verhalten.<br />

Spezielle Implementations-Eigenschaften von Attributen u.a. Typen (meaning)<br />

1. Zeitinvariante Attribute (kein update) (eigentlich aber eine Implementationseinschränkung (es ist nichts in<br />

<strong>der</strong> ‘real world’ zeitinvariant))<br />

Vorteil: keine Inkonsistenz von Attributwerten (beson<strong>der</strong>s bei Frendschlüsseln bzw. referentieller Integrität - einfache<br />

Pflege)<br />

<strong>2.</strong> Einelementige Schlüssel<br />

Vorteil: einfache Organisation<br />

3. (Keine-Nullwerte)-Beschränkung (Totalität von Attributen)<br />

Vorteil: verwendbar für alles<br />

4. Ausschluß von Hierarchien<br />

Vorteil: lesbare und einfache Darstellung von Objekten<br />

5. Totale, ausschließliche Schlüssel<br />

Vorteil: Standardrepräsentation, updates sind eindeutig, unique-meaning-assumption, universal-relation-assumption<br />

6. Default-Werte anstatt Nullwerte<br />

Vorteil: updates einfacher<br />

Nachteil: Anfragen verschieden interpretierbar<br />

Aber Preis dafür ist hoch:<br />

• Schemas weit entfernt vom Verständnis<br />

• inflexibel, unnatürlich, redundant<br />

• Integritätsbedingungen unterrepräsentiert<br />

• Anfragen sind schwierig darzustellen<br />

Auffinden <strong>der</strong> gesuchten Information<br />

Auswahl bestimmter Objekte durch Spezifikation:<br />

<strong>der</strong> Benutzer beschreibt die Zeile (o<strong>der</strong> Zeilen) mit Hilfe von Mengenoperationen (Relationenalgebra) (Welche<br />

Information soll aus <strong>der</strong> Datenbank geliefert werden?)<br />

Ergebnisrelation


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 7<br />

<strong>2.</strong>1.7 Einführung in die Theorie relationaler <strong>Datenbanken</strong><br />

Wertebereichsschema als Basis-Datentypen:<br />

DT (D) = (domain(D), Ops(D), P red(D)<br />

mit Wertebereich, Operationen, Prädikaten (mindestens =)<br />

Universum <strong>der</strong> relationalen Datenbank: U = {A 1 , ..., A n }<br />

Datenschema BT = (U = {A 1 , ..., A n }, {DT (D 1 ), ...., DT (D m )}, dom)<br />

mit dom : U → {DT (D 1 ), ...., DT (D m )}<br />

Relationenschema R = (R, X, Σ) über Datenschema BT<br />

primärer Schlüssel X bzw. Menge von Schlüsseln K ⊆ 2 R , die Sperner-Menge bildet X, Y ∈ K ⇒ X ⊈ Y<br />

Integritätsbedingungen Σ<br />

Tupel als Funktion t : R → ∪ A∈R dom(A) mit t(A) ∈ dom(A)<br />

mitunter auch partielle Funktionen zugelassen<br />

Instanz (Ausprägung) als Menge von Tupeln<br />

auch Klasse genannt<br />

SAT (R)<br />

je<strong>der</strong> Attributname beschreibt eine von n Eigenschaften eines Objektes<br />

dom(A j ) Menge von atomaren Werten, die Objekte bzgl. A j annehmen können<br />

R beschreibt eine Klasse von Objekten<br />

Relation R C stellt Klasse von Objekten dar<br />

Reihenfolge <strong>der</strong> Tupel und <strong>der</strong> Attribute nicht relevant, da Relation und Attributmenge<br />

1. Normalform: alle Attribute sind atomar<br />

Dafür:<br />

umfangreiche Theorie <strong>der</strong> Integritätsbedingungen<br />

aufgrund <strong>der</strong> Mengendefinition: Jede Relation hat mindestens einen Schlüssel: R<br />

maximale Schlüsselanzahl:<br />

( ) ‖R‖<br />

⌊ ‖R‖<br />

2 ⌋<br />

läßt sich die Relationengröße abschätzen und bleibt relativ stabil, dann sind fast alle minimalen Schlüssel von <strong>der</strong><br />

Länge 2 ∗ log |dom(R)| (|R C |)<br />

funktionale Abhängigkeiten X −→ Y<br />

Gültigkeit von funktionalen Abhängigkeiten<br />

zwei Tupel mit gleichen X-Werten haben auch gleiche Y -Werte<br />

Beispiele:<br />

VORLESUNG: { Kurs, Semester } −→ { Lesen<strong>der</strong>, Zeit, Raum }<br />

VORLESUNG: { Semester, Raum, Zeit} −→ { Kurs }<br />

STUDENT: { PNum } −→ { SNum }<br />

STUDENT: { SNum } −→ { PNum }<br />

Axiomatisierung für jeweils einen Typen<br />

Axiome<br />

X ∪ Y<br />

−→ Y


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 8<br />

Regeln<br />

X −→ Y<br />

X ∪ Z ∪ W −→ Y ∪ Z<br />

X −→ Y , Y −→ Z<br />

X −→ Z<br />

weitere Regeln:<br />

X −→ Y , Y ∪ W −→ Z<br />

X ∪ W −→ Z<br />

X −→ Y , X −→ Z<br />

X −→ Y ∪ Z<br />

X −→ Y ∪ Z<br />

X −→ Z<br />

Theorem 1 Diese Axiomatisierung ist korrekt und vollständig.<br />

Hüllenkonstruktion mit Schalen<br />

Σ 1 := {X −→ {A} | A ∈ Y for X −→ Y ∈ Σ}<br />

X 0 := X<br />

X i+1 := {A | Z ⊆ X i , Z −→ {A} ∈ Σ 1 }<br />

Lemma 1 Aus Y ⊆ X ∗ folgt Σ |= X −→ Y<br />

Beweis: Nachrechnen <strong>der</strong> Regeln<br />

Lemma 2 Σ |= X −→ X +<br />

Beweis: durch Induktion über die Schalen <strong>der</strong> Hüllenkonstruktion<br />

i = 0 : Reflexivität<br />

i+1: Annahme gültig für i-Schale<br />

d.h. X −→ X i is in R C gültig<br />

Induktionsziel: X −→ X i+1 is in R C gültig<br />

damit gilt insbeson<strong>der</strong>e für Objekte mit t = X t ′ auch t = Xi t ′<br />

Es sei nun V −→ W in R C gültig<br />

Fall 1: V ⊈ X “nothing to prove”<br />

Fall 2: V ⊆ X : damit falls t = V t ′ für t, t ′ ∈ R C damit auch wegen Gültigeit in R C t = W t ′<br />

Zum an<strong>der</strong>en aber : aufgrund <strong>der</strong> Schalenkonstruktion <strong>der</strong> Hülle:<br />

t = Xi+1 t ′<br />

Lemma 3 Y ⊆ X ∗ falls Σ |= X −→ Y<br />

Beweis über die Konstruktion einer Kontraposition<br />

Armstrong-Relation R C mit <strong>der</strong> gezeigt werden kann Y ⊈ X +<br />

Kontraposition: t, t ′ mit t(A) = t ′ (A) gdw. A ∈ X +<br />

1. {t, t ′ } ̸|= X −→ Y für eine X −→ Y ∈ Σ


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 9<br />

damit auch ein Attribut von Y nicht Element von X +<br />

damit Eigenschaft erfült<br />

<strong>2.</strong> {t, t ′ } |= Σ<br />

gegeben nun V −→ W ∈ Σ<br />

Fall 1 : {t, t ′ } |= V −→ W wegen t ≠ V t ′<br />

Fall 2 : t = V t ′ damit auch W ⊆ X ∗ wegen vorigen Lemmas<br />

damit auch t = X t ′ und somit {t, t ′ } |= V −→ W<br />

Schichtung und graphische Darstellung für funktionale Abhängigkeiten<br />

Beispiel:<br />

{ PersNr } −→ { Name, Raum, PLZ, Straße }<br />

{ Raum } −→ { PersNr }<br />

{ Ort, Bundesland, Straße } −→ { PLZ }<br />

{ PLZ } −→ { Ort, Bundesland }<br />

{ Ort, Bundesland } −→ { Vorwahl, Einwohneranzahl }<br />

{ Bundesland } −→ { ParteiMinisterpräsident }<br />

mehrwertige Abhängigkeiten X → Y<br />

Gültigkeit mehrwertiger Abhängigkeiten<br />

mehrere äquivalente Definitionen:<br />

• Die Y -Werte hängen von den X-Werten prädikativ ab und nur von diesen.<br />

(σ X=x (R C ))[Y ] = (σ X=x∧Z=z (R C ))[Y ] Z = R \ (X ∪ Y )<br />

Durch Z-Werte kann man die tupel nicht genauer unterscheiden, wenn man die X-Werte schon zur Unterscheidung<br />

herangezogen hat.<br />

• Stimmen zwei Tupel über X überein, dann exisitiert ein drittes Tupel, das Werte vom ersten Tupel über<br />

X ∪ Y und vom zweiten Tupel über X ∪ (R \ Y ) übernimmt.<br />

∀t 1 , t 2 ∃t 3 ((P R (t 1 ) ∧ P R (t 1 ) ∧ t 1 = X t 2 ) −→ (P R (t 3 ) ∧ t 1 = X∪Y t 3 ∧ t 2 = X∪Z t 3 ))<br />

• Die Relation läßt sich in <strong>der</strong> genesteten Form X, Y \ X, R \ (X ∪ Y ) darstellen.<br />

X Y \ X R \ (X ∪ Y )<br />

A 1 ... A k B 1 ... B l C 1 ... C m<br />

... ... ... ... ... ... ... ... ...<br />

• Man kann die Relation verlustfrei zerlegen in eine Projektion über X ∪ Y und über X ∪ (R \ Y ). Alle Tupel<br />

und nur diese lassen sich aus diesen Projektionen wie<strong>der</strong>gewinnen.<br />

Beispiele:<br />

STUDENT: { PNum } → { Nebenf }<br />

STUDENT: { SNum } → { Betreuer }<br />

Axiomatisierung gemeinsam mit funktionalen Abhängigkeiten<br />

Axiome<br />

X ∪ Y −→ Y ; X ∪ Y → Y | Z<br />

Regeln<br />

X → Y | Z<br />

X → Z | Y<br />

X −→ Y<br />

X ∪ V ∪ W −→ Y ∪ V<br />

X −→ Y , Y −→ Z<br />

X −→ Z<br />

X ∪ Y ∪ Z → V | W ∪ U , X → Y ∪ V ∪ W | Z ∪ U<br />

X ∪ Y → V | Z ∪ W ∪ U<br />

X −→ Y<br />

X → Y | Z Z = attr(R) − (X ∪ Y ) X → Y | V , Z −→ W<br />

X −→ W<br />

W ⊆ Y, Y ∩ Z = ∅ .


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 10<br />

Verbundabhängigkeiten (X 1 , ...X m )<br />

X 1 ∪ ... ∪ X m = R<br />

Gültigkeit <strong>der</strong> Verbundabhängigkeiten<br />

Man kann die Relation verlustfrei zerlegen in eine Projektion über X 1 , ... über X m . Alle Tupel und nur diese lassen<br />

sich aus diesen Projektionen wie<strong>der</strong>gewinnen.<br />

Inklusionsabhängigkeiten R[X] ⊆ S[Y ]<br />

auch zur Darstellung <strong>der</strong> referentiellen Integrität (Tupel, die von Tupelns an<strong>der</strong>er Relationen referenziert werden)<br />

(Existenzbedingung)<br />

Gültigkeit <strong>der</strong> Inklusionsabhängigkeiten<br />

Die X-Werte von R C kommen in S C [Y ] vor.<br />

Beispiel:<br />

VORLESUNGSBESUCH[Student] ⊆ STUDENT[SNum]<br />

Exklusionsabhängigkeiten R[X]||S[Y ]<br />

Gültigkeit <strong>der</strong> Exklusionsabhängigkeiten<br />

Die X-Werte von R C kommen nicht in S C [Y ] vor.<br />

Beispiel:<br />

VORLESUNGSBESUCH[Student] || VORLESUNGSBESUCH[Lesen<strong>der</strong>]<br />

weitere Bedingungen über funktionale und mehrwertige Abhängigkeiten<br />

siehe auch Entwurfstheorie - hier nur im Vorgriff<br />

<strong>2.</strong> Normalform Teilschlüssel implizieren nicht Nicht-Schlüsselattribute<br />

3. Normalform jedes Nicht-Schlüssel-Attribut darf nur direkt von einem Schlüssel abhängen (kein transitiver<br />

Schluß)<br />

Boyce-Codd-Normalform jede nicht-triviale funktionale Abhängigkeit ist eine Schlüsselabhängigkeit<br />

4. Normalform jede geltende mehrwertige Abhängigkeit ist ableitbar aus den geltenden Schlüsselabhängigkeiten<br />

5. Normalform jede geltende Verbundabhängigkeit ist ableitbar aus den geltenden Schlüsselabhängigkeiten<br />

Einfüge-, Lösch- und Update-Anomalien treten genau dann nicht auf, wenn nur funktionale Abhängigkeiten gelten<br />

und Relationenschema in BCNF ist<br />

<strong>2.</strong>2 Die relationale Algebra<br />

<strong>2.</strong><strong>2.</strong>1 Operationen <strong>der</strong> Relationenalgebra und ihre Eigenschaften<br />

Operationen <strong>der</strong> Relationenalgebra<br />

Selektion: Auswahl einer Zeile mit bestimmten Wertemerkmalen (erfüllen gestellte Bedingung)<br />

Projektion: Auswahl von Teilen von Zeilen (Spalten)<br />

Verbund: Verknüpfung zweier Tabellen zu eienr Tabelle, die alle Attribute bei<strong>der</strong> Tabellen enthält; Zeilen <strong>der</strong> Ergebnistabelle<br />

bestehen aus Verkettung einer Zeile <strong>der</strong> ersten Tabelle und einer Zeile <strong>der</strong> zweiten Tabelle, wobei


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 11<br />

diese beiden Zeilen in den gemeinsamen Attributen übereinstimmen müssen (dadurch kann Doppelung weggelassen<br />

werden)<br />

Mengenoperationen: Vereinigung, Durchschnitt, Mengendifferenz<br />

Operationen des relationalen Modelles<br />

• Für R C , R ′C R = (R, X, Σ) :<br />

• R C ∪ R ′C (Vereinigung),<br />

• R C ∩ R ′C (Durchschnitt) und<br />

• R C \ R ′C (Mengen- Differenz)<br />

• D R DD \ RC Komplement unsafe !!<br />

• Für R C ∈ SAT (R), A, C ∈ {B 1 , ..., B n }, Wert a ∈ dom(A), Vergl.-op. θ ∈ {≤, ≥, ≠, =, },<br />

Selektionen σ Aθa , σ AθC sind die Teilmengen {t ∈ R C | t(A)θa} und {t ∈ R C | t(A)θt(C)} von R C .<br />

Für t über Y ⊆ R Beschränkung von R C nach t ist definiert: σ t (R C ) = {t ′ ∈ R C | t ′ [X] = t}<br />

• Operationen zwischen Schemata:<br />

Für Tupel t über R und Teilmenge Y ⊆ R Projektion von t auf X, t[Y ] : Einschränkung von t auf Y<br />

Projektion R C [Y ] = π X (R C ) von R C auf Y : {t[Y ] | t ∈ R C }<br />

Attributabbildungsfunktion η : R −→ S<br />

η-Projektion π η (R C ) = {s ∈ D S DD |∃t ∈ RC : s = η(t)}<br />

damit Projektion, Umbenennung, Vervielfachung von Spalten<br />

• Zwei Schemas R = (R, X, Σ), R ′ = (R ′ , X ′ , Σ ′ ) und Relationen R C , R ′C<br />

• (natürlicher) Verbund R C ✶ R ′C von R C , R ′C<br />

{t | t[{B 1 , ..., B n }] ∈ R C , t[{B ′ 1 , ..., B′ n ′ }] ∈ R ′C } definiert über R ∪ R ′<br />

• allgemeiner Verbund (Theta-Join)<br />

• kartesisches Produkt - R ∩ R ′ = ∅ - natürlicher Verbund<br />

• Teilverbund (semijoin o<strong>der</strong> equi-semijoin) R C ×⊲ S C = R C ✶ π R∩S (S C )<br />

• verallgemeinerte Vereinigung R C + S C = {τ ∈ D R∪S<br />

DD |τ(R) ∈ RC ∨ τ(S) ∈ S C }<br />

• Division (Quotient) R C /S C = {τ ∈ D R\S<br />

DD |∀ν ∈ π R∩S(S C ) : {τ} ∪ {ν} ⊆ R C }<br />

= {τ ∈ π R∩S (R C )|{τ} ✶ π R∩Y (S C ) ⊆ R C }<br />

Die Division ist darstellbar durch<br />

π R−S (R C ) \ π R−S ((π R−S (R C ) × S) \ R) for R − S = attr(R) \ attr(S).<br />

Diese Operation is wichtig für die horizontale Reduktion o<strong>der</strong> Dekomposition. Man kann R C /S C<br />

nutzen zur Wie<strong>der</strong>gewinnung von R C durch<br />

R C = (π attrR ((R C /S C ) × S C )) ∪ (R C \ R C /S C )<br />

Umschreibung: ∀s ∈ S C ∃t ∈ R C : s[attr(S) ∩ attr(R)] = t[attr(S) ∩ attr(R)]<br />

damit ist ein Generalisator mit gegeben.<br />

Die Division wird oft auch mit R C ÷ S C angegeben.<br />

Ein Beispiel einer auf diese Art einfach formulierbaren Anfrage ist<br />

Alle Studenten, die alle Vorlesungen von Thalheim hörten:<br />

Teilnahme ÷ π V orlesNr (σ Dozent=“T halheim ′′(V orlesung)).<br />

• linker äußerer Verbund<br />

R C –✶ S C = R C ✶ S C ∪<br />

{t×NULL ∈ dom(attr(R)∪attr(S)|π attr(R)∩attr(S) (t) ∉ π attr(R)∩attr(S) (S C )}


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 12<br />

• rechter äußerer Verbund<br />

R C ✶– S C = R C ✶ S C ∪<br />

{NULL×t ∈ dom(attr(R)∪attr(S)|π attr(R)∩attr(S) (t) ∉ π attr(R)∩attr(S) (R C )}<br />

• voller äußerer Verbund<br />

• linker Halb-Verbund (left Semi-Join) R C ⋉ S C = π attr(R)\attr(S) (R C ✶ S C )<br />

• rechter Halb-Verbund (right Semi-Join) R C ⋊ S C = π attr(S)\attr(R) (R C ✶ S C )<br />

• Algebra mit Nullwerten<br />

Vorsicht: Ist durch Nullwerte verschieden von bisher betrachteter Algebra!<br />

Nullwerte haben mindestens 14 verschiedene Bedeutungen. Gewöhnlich betrachten wir als Bedeutungen<br />

• (a) unbekannt (no information, unknown)<br />

• (b) not applicable<br />

• (c) not existent<br />

Die Anfragen σ Note


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 13<br />

• Eigenschaften :<br />

• Verbund: kommutativ, assoziativ,<br />

monoton (R C ⊆ S C ⇒ R C ✶ T C ⊆ S C ✶ T C ),<br />

absorbtiv (R C ⊆ R t+ ⇒ R C ✶ R t+ = R C ),<br />

idempotent, R C ✶ ∅ = ∅<br />

R C ✶ S C = R C × S C falls R ∩ S = ∅<br />

R C ✶ S C = R C ∪ S C falls R = S<br />

•<br />

⎧<br />

⎨ σ A=c (R C ) ✶ S C<br />

σ A=c (R C ✶ S C ) = σ<br />

⎩ A=c (R C ) ✶ σ A=c (S C )<br />

R C ✶ σ A=c (S C )<br />

falls A ∈ R \ S<br />

falls A ∈ R ∩ S<br />

falls A ∈ S \ R<br />

• R C ⊆✶ k i=1 π X i<br />

(R C ) für ∪ k i=1 X i = R<br />

• π Xj (✶ k i=1 RC i ) ⊆ RC j<br />

• R C =✶ k i=1 π X i<br />

(R C ) dann gilt die Verbundabhängigkeit (X 1 , ...X k ) in R C<br />

• π X (R C ✶ S C ) = π X (R C ) ✶ π X (S C ) falls R ∩ S ⊆ X<br />

• π X (σ A=c (R C ) = σ A=c (π X (R C )) falls A ∈ X ∩ R<br />

• π X (π Y (R C )) = π X∩Y (R C )<br />

• verallgemeinerte Vereinigung ist kommutativ, idempotent, monoton, assoziativ, distributiv mit Verbund<br />

• Selektion σ A=c , σ A≠c definieren Partition<br />

• σ X=Y (R C ) = σ A1 =B 1<br />

(σ A2 =B 2<br />

(...σ Am =B m<br />

(R C )...)) für X = A 1 , ...A m , Y = B 1 , ..., B m<br />

• (R C ✶ S C )/S C = R C falls R ∩ S = ∅<br />

r C /S C = π R\S (R C ) \ π R\S ((π R\S (R C ) ✶ π R∩S (S C )) \ R C )<br />

• R = (R, X, Σ), Attribute A ∈ R, B ∈ U \ {B 1 , ..., B n } Relation R C Umbenennung ϱ A|B (R C ) :<br />

{t | for some t ′ ∈ R C : t(B) = t ′ (A), t[{B 1 , ..., B n } \ {A}] = t ′ [{B 1 , ..., B n } \ {A}]}<br />

über ({B 1 , ..., B n } \ {A}) ∪ {B}<br />

• Strukturelle Rekursion Gegeben T , T ′ , Kollektionstypen C T über T (d.h. Wertemengen vom Typ T , Multimengen,<br />

Listen)<br />

Operationen wie verallgemeinerte Vereinigung ∪ C T , verallgemeinerten Durchschnitt ∩ C T , verallgemeinertes<br />

leeres Element ∅ C T von C T<br />

gegeben h 0 über T ′ und 2 Funktionen<br />

h 1 : T → T ′ h 2 : T ′ × T ′ → T ′ .<br />

• Strukturelle Rekursion mit Insert-Definition für R C über T<br />

srec h0 ,h 1 ,h 2<br />

(∅ C T ) = h 0<br />

srec h0 ,h 1 ,h 2<br />

({|s|}) = h 1 (s) für ein-elementige Kollektionen {|s|}<br />

srec h0 ,h 1 ,h 2<br />

({|s|} ∪ C T R C ) = h 2 (h 1 (s), srec h0 ,h 1 ,h 2<br />

(R C )) gdw. {|s|} ∩ C T R C = ∅ C T .<br />

• Strukturelle Rekursion über Vereinigungs-Definition<br />

srec h0 ,h 1 ,h 2<br />

(∅ C T ) = h 0<br />

srec h0 ,h 1 ,h 2<br />

({|s|}) = h 1 (s) für einelementige Kollektionen {|s|}<br />

srec h0 ,h 1 ,h 2<br />

(R1 C ∪ C T RC 2 ) = h 2(srec h0 ,h 1 ,h 2<br />

(R1 C), srec h 0 ,h 1 ,h 2<br />

(R2 C)) gdw. RC 1 ∩ C T RC 2 =<br />

∅ C T .<br />

• Einschränkung auf Funktionen h 0 =⊥, Vereinigung ∪ T ′, Nullelement ⊥ of T ′<br />

dann immer wohldefiniert<br />

• eingeschränkte strukturelle Rekursion definiert durch Funktion h 1<br />

d.h. Erweiterung <strong>der</strong> Funktion h 1<br />

ext(h 1 )(R C ) = srec ⊥,h1 ,∪ T ′ (R C ) .


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 14<br />

Äquivalent zu comprehensions<br />

• allgemeine Aggregation pump definiert durch strukturelle Rekursion mit T ′ = IN<br />

Beispiele:<br />

• sum mit Startwert 0 und + für h 2<br />

d.h. pump = srec 0,h1 ,+ = ext(h 1 )<br />

• map - restrukturiert jedes Element über T<br />

Typ T ′ ist Kollektionstype<br />

mit einem Paramenter h 1 und für R C ⊆ T C wird <strong>der</strong> Wert {h 1 ({s}) | s ∈ R C } erzeugt, d.h.<br />

srec ∅,h1 ,∪ = ext(h 1 )<br />

nest basiert auf einer Äquivalenzrelation über einem o<strong>der</strong> mehreren Attributen von T C mit gemeinsamen<br />

Werten und Kombinator h 2<br />

• filter Operation über splitting von h 1 und h 2 = ∪, T ′ = {T }, d.h. srec ∅,h1 ,∪ = ext(h 1 )<br />

definiert über Formeln α von L T mit einer freien Variablen x ( α = α(x), filter = filter α )<br />

h 1 ({s}) =<br />

{ {s} if |= α(s)<br />

if ̸|= α(s)<br />

h 0<br />

• SQL-Ausdruck <strong>der</strong> Form Select ... From ... Where ... sind Ausdrücke <strong>der</strong> Form map(filter(...))<br />

• Group By ... Konstrukt - spezieller map Ausdruck<br />

Beispiele zur relationalen Algebra.<br />

(aus dem Material 1 <strong>der</strong> vorangegangenen Jahre)<br />

Relationen sind Mengen von Tupeln. Deshalb lassen sich die üblichen Mengenoperationen auf Relationen anwenden.<br />

Seien R un S zwei Relationen über denselben Attributen. Dann ist<br />

Beispiele:<br />

MITARBEITER<br />

Name Wohnort<br />

Max Müller<br />

Tina Schmidt<br />

Klaus Meyer<br />

Kiel<br />

Lübeck<br />

Kiel<br />

MITARBEITER ∪ STUDENTEN<br />

Name Wohnort<br />

Max Müller<br />

Tina Schmidt<br />

Klaus Meyer<br />

Andre Petersen<br />

Thomas Ebert<br />

Kiel<br />

Lübeck<br />

Kiel<br />

Hamburg<br />

Rendsburg<br />

MITARBEITER \ STUDENTEN<br />

Name<br />

Wohnort<br />

R ∪ S = {t|t ∈ R ∨ t ∈ S}<br />

R ∩ S = {t|t ∈ R ∧ t ∈ S}<br />

R\S = {t|t ∈ R ∧ t /∈ S}<br />

STUDENTEN<br />

Name<br />

Max Müller<br />

Andre Petersen<br />

Thomas Ebert<br />

Wohnort<br />

Kiel<br />

Hamburg<br />

Rendsburg<br />

MITARBEITER ∩ STUDENTEN<br />

Name Wohnort<br />

Max Müller<br />

Tina Schmidt Lübeck<br />

Klaus Meyer Kiel<br />

Wichtig: die Mengenoperationen sind nur für Relationen mit denselben Attributen definiert!<br />

1 Dieser Teil des Skriptum wurde von G. Fiedler (mein Dank dafür) erstellt.<br />

Kiel


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 15<br />

Selektion.<br />

Mit Hilfe <strong>der</strong> Selektion werden auf Grundlage einer gegebenen aussagenlogischen Formel die Tupel aus einer<br />

Relation ausgewählt, die diese Formel erfüllen. Die Formel ϕ darf nur Aussagen über Attribute enthalten, die in R<br />

vorhanden sind.<br />

Beispiele:<br />

σ W ohnort= ′ Kiel ′(MITARBEITER)<br />

Name Wohnort<br />

σ ϕ (R) = {t|t ∈ R ∧ t |= ϕ}<br />

Max Müller Kiel<br />

Klaus Meyer Kiel<br />

MITARBEITER ∪ (σ W ohnort= ′ Rendsburg ′(STUDENTEN))<br />

Name<br />

Max Müller<br />

Tina Schmidt<br />

Klaus Meyer<br />

Thomas Ebert<br />

Projektion.<br />

Wohnort<br />

Kiel<br />

Lübeck<br />

Kiel<br />

Rendsburg<br />

Die Projektion erstellt aus einer gegebenen Relation eine neue Relation, indem sie nur eine Teilmenge <strong>der</strong> vorhandenen<br />

Attribute auswählt. Während die Selektion Tupel auswählt, also bildlich gesprochen ”<br />

Zeilen entfernt“,<br />

wählt die Projektion Attribute aus, d.h. es werden ”<br />

Spalten entfernt“. Die Liste <strong>der</strong> Attribute, die in die Zielrelation<br />

übernommen werden sollen, werden <strong>der</strong> Projektion als Parameter mitgegeben. Die Menge <strong>der</strong> Zielattribute muß<br />

natürlich eine (echte o<strong>der</strong> unechte) Teilmenge <strong>der</strong> Attribute <strong>der</strong> gegebenen Relation sein. Man beachte, daß Relationen<br />

Mengen sind. Falls durch die Projektion doppelte Tupel entstehen, fallen diese zu einem einzigen Tupel in <strong>der</strong><br />

Zielrelation zusammen. Da wir Tupel als Funktionen definiert haben, die Attribute auf Werte abbilden, können wir<br />

die Projektion als Einschränkung des Definitionsbereichs <strong>der</strong> Funktion auf die gewünschten Attribute definieren.<br />

Beispiele:<br />

π Name (STUDENTEN)<br />

Name<br />

Max Müller<br />

Andre Petersen<br />

Thomas Ebert<br />

π W ohnort (MITARBEITER)<br />

Wohnort<br />

Kiel<br />

Lübeck<br />

Umbenennung.<br />

π A1 ,...,A n<br />

(R) = {t| A1 ,...,A n<br />

| t ∈ R}<br />

Die Umbenennung gibt einem Attribut einen neuen Namen. Die Wertebereichsfunktion muß diese Umbenennung<br />

zulassen, d.h. die Datentypen des alten und des neuen Attributs müssen identisch sein. Außerdem darf <strong>der</strong><br />

neue Attributname noch nicht in <strong>der</strong> Menge <strong>der</strong> Attribute <strong>der</strong> Relation enthalten sein. Sei attr(R) die Menge <strong>der</strong><br />

Attribute <strong>der</strong> Relation R:<br />

ϱ A→B (R) = {t| attr(R)\{A} ∪ {(B, t(A))} | t ∈ R}


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 16<br />

Natürlich kann man mehrere Attribute “in einem Rutsch” umbenennen. Dabei schreibt man die einzelnen Umbenennungen<br />

mit Komma getrennt als Parameter des Operators. Dies ist dann identisch mit <strong>der</strong> Nacheinan<strong>der</strong>ausführung<br />

<strong>der</strong> einzelnen Umbenennungen.<br />

Beispiel:<br />

ϱ W ohnort→Ort (STUDENTEN)<br />

Name Ort<br />

Max Müller<br />

Andre Petersen<br />

Thomas Ebert<br />

Natürlicher Verbund.<br />

Kiel<br />

Hamburg<br />

Rendsburg<br />

Der natürliche Verbund wird benutzt, um zwei Relationen zu verbinden. Die Attribute <strong>der</strong> beiden Relationen R<br />

und S lassen sich in drei Gruppen einteilen:<br />

1. Attribute, die in R, aber nicht in S vorkommen<br />

<strong>2.</strong> Attribute, die in S, aber nicht in R vorkommen<br />

3. Attribute, die in beiden Relationen vorkommen<br />

Die Attribute <strong>der</strong> dritten Kategorie bilden das ”<br />

verbindende Element“ <strong>der</strong> beiden Relationen. Wir erzeugen die<br />

Tupel t <strong>der</strong> Ergebnisrelation R ⊲⊳ S so, daß<br />

1. wenn wir t auf die Attribute von R projizieren, ein gleiches Tupel in R existiert und<br />

<strong>2.</strong> wenn wir t auf die Attribute von S projizieren, ein gleiches Tupel in S existiert.<br />

Daraus folgt, daß wir alle Paare von Tupeln r ∈ R und s ∈ S betrachten, die in den gemeinsamen Attributen<br />

(Kategorie drei) die gleichen Werte haben. Wir verbinden die beide Tupel r und s zu t und fügen t zur Ergebnisrelation<br />

hinzu.<br />

R ⊲⊳ S = {t | t| attr(R) ∈ R ∧ t| attr(S) ∈ S}<br />

Wenn wir uns einen Algorithmus zum Berechnen des natürlichen Verbunds zweier Relationen überlegen,<br />

können wir u.a. den Nested-Loop-Join“ anwenden. Seien A ” 1 , ..., A n die gemeinsamen Attribute <strong>der</strong> Relationen R<br />

und S, dann berechnet sich <strong>der</strong> natürliche Verbund T = R ⊲⊳ S folgen<strong>der</strong>maßen:<br />

T := ∅<br />

FORALL r IN R DO<br />

FORALL s IN S DO<br />

IF r.A 1 = s.A 1 AND ... AND r.A n = s.A n THEN<br />

t := r ∪ s<br />

T := T ∪ {t}<br />

END IF<br />

END FOR<br />

END FOR<br />

RETURN T<br />

Weitere (effizientere) Algorithmen zur Berechnung des natürlichen Verbunds werden wir später kennenlernen.<br />

Beispiele:


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 17<br />

VORLESUNG<br />

Kuerzel Bezeichnung<br />

SysInf IV<br />

Info III<br />

Info II<br />

SysInf I<br />

<strong>Datenbanken</strong> I<br />

Softwaretechnologie<br />

Algorithmen und Datenstrukturen<br />

Digitale Systeme<br />

STUDENTEN ⊲⊳ HOERT<br />

Name Wohnort Kuerzel<br />

Max Müller Kiel SysInf IV<br />

Max Müller Kiel Info III<br />

Andre Petersen Hamburg Info II<br />

Andre Petersen Hamburg Info III<br />

STUDENTEN ⊲⊳ HOERT ⊲⊳ VORLESUNG<br />

Name Wohnort Kuerzel Bezeichnung<br />

HOERT<br />

Name<br />

Max Müller<br />

Max Müller<br />

Andre Petersen<br />

Andre Petersen<br />

Kuerzel<br />

Max Müller Kiel SysInf IV <strong>Datenbanken</strong> I<br />

Max Müller Kiel Info III Softwaretechnologie<br />

Andre Petersen Hamburg Info II Algorithmen und Datenstrukturen<br />

Andre Petersen Hamburg Info III Softwaretechnologie<br />

π Name,Bezeichnung ((σ W ohnort= ′ Kiel ′(STUDENTEN)) ⊲⊳ HOERT ⊲⊳ VORLESUNG)<br />

Name<br />

Bezeichnung<br />

SysInf IV<br />

Info III<br />

Info II<br />

Info III<br />

Max Müller <strong>Datenbanken</strong> I<br />

Max Müller Softwaretechnologie<br />

Der Student Max Müller hört die Veranstaltungen mit den Kürzeln SysInf IV“ und Info III“. Wenn wir die<br />

” ”<br />

Relationen STUDENTEN und HOERT verbinden, ist Name das einzige gemeinsame Attribut. Wir schauen also<br />

alle Tupel in STUDENTEN an. Für jeden gefundenen Studenten schauen wir uns alle Tupel in HOERT an. Wenn<br />

wir einen Studenten und ein HOERT-Tupel finden, die im Attribut Name übereinstimmen, dann verbinden wir die<br />

beiden Tupel und fügen das neue Tupel zum Ergebnis hinzu. Da <strong>der</strong> Student Thomas Ebert keine Veranstaltung<br />

hört, fällt er aus dem Ergebnis heraus.<br />

Auf die gleiche Art und Weise können wir das so entstandene Ergebnis mit <strong>der</strong> Relation VORLESUNG verbinden.<br />

Kuerzel ist das verbindende Attribut. Da die Veranstaltung SysInf I“ von keinem Studenten gehört wird,<br />

”<br />

taucht sie in <strong>der</strong> Ergebnisrelation nicht auf.<br />

Falls die beiden Relationen R und S keine gemeinsamen Attribute haben, wird das Kreuzprodukt bei<strong>der</strong> Relationen<br />

gebildet, d.h. jedes Tupel aus R wird mit jedem Tupel aus S verknüpft.<br />

Division.<br />

Der Divisionsoperator erlaubt die kompakte Formulierung von für-alle“-Anfragen. Betrachten wir folgende<br />

”<br />

Relationen:<br />

HOERT<br />

VORLESUNG<br />

Name Kuerzel<br />

Kuerzel Bezeichnung<br />

Max Müller SysInf IV<br />

SysInf IV <strong>Datenbanken</strong> I<br />

Max Müller Info III<br />

Info III Softwaretechnologie<br />

Max Müller Info II<br />

Info II Algorithmen und Datenstrukturen<br />

Max Müller SysInf I<br />

SysInf I Digitale Systeme<br />

Andre Petersen Info II<br />

Andre Petersen Info III<br />

Wenn man jetzt die Anfrage Welcher Student hört alle Vorlesungen“ stellt, dann suchen wir die Namen, für<br />

”<br />

die für jedes Kürzel in <strong>der</strong> Relation VORLESUNG ein passendes Tupel in <strong>der</strong> Relation HOERT existiert (in unserem<br />

Beispiel ist dies Max Müller.) Das leistet <strong>der</strong> Divisionsoperator:<br />

HOERT ÷ (π Kuerzel (VORLESUNG))


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 18<br />

Name<br />

Max Müller<br />

Formal gesprochen: es existieren zwei Relationen R und S, wobei die Attributmenge <strong>der</strong> Relation S eine echte<br />

Teilmenge <strong>der</strong> Attributmenge von R ist: attr(S) attr(R). Das Ergebnis <strong>der</strong> Division ist eine Relation über<br />

den Attributen, die in R, aber nicht in S vorkommen (attr(R ÷ S) = attr(R)\attr(S)). Diese Relation enthält<br />

genau die Tupel t, die aus einem Tupel r ∈ R durch Projektion auf attr(R)\attr(S) entstehen, so daß man dieses<br />

Tupel mit allen Tupeln s ∈ S ergänzen kann, um wie<strong>der</strong> ein Tupel aus R zu erzeugen. Mit an<strong>der</strong>en Worten: das<br />

Ergebnistupel t steht in R mit allen Tupeln <strong>der</strong> Relation S ”<br />

in Beziehung“:<br />

Anfragebeispiele.<br />

R ÷ S = {t | attr(t) = attr(R)\attr(S) ∧ {t} ⊲⊳ S ⊆ R}<br />

Wir wenden nun die vorgestellten Operationen an, um Anfragen an ein Beispielschema zu stellen. Wichtig:<br />

wir stellen Anfragen immer gegen ein Datenbankschema, nicht gegen einen konkreten Datenbankzustand. Die<br />

Auswertung <strong>der</strong> Anfrage erfolgt stets bzgl. eines konkreten Datenbankzustandes. Unsere Anfrage muß aber für<br />

alle gültigen Zustände unseres Schemas funktionieren.<br />

Wir benutzen folgendes Beispielschema (Primärschlüssel sind unterstrichen):<br />

{<br />

STUDENT({MatrikelNr,Name,Wohnort}),<br />

MITARBEITER({BearbeiterNr,PersonalNr,Name,Wohnort}),<br />

VORLESUNG({VorlesungsNr,Bezeichnung}),<br />

DOZENT({BearbeiterNr,PersonalNr,VorlesungsNr}),<br />

HOERT({MatrikelNr,VorlesungsNr,Wie<strong>der</strong>holung}),<br />

FINDETSTATT({VorlesungsNr,Zeit,RaumNr}),<br />

RAUM({RaumNr,Bezeichnung})<br />

}<br />

Folgende Fremdschlüssel sind definiert:<br />

DOZENT [BearbeiterNr, P ersonalNr] ⊆ MIT ARBEIT ER[BearbeiterNr, P ersonalNr]<br />

DOZENT [V orlesungsNr] ⊆ V ORLESUNG[V orlesungsNr]<br />

HOERT [MatrikelNr] ⊆ ST UDENT [MatrikelNr]<br />

HOERT [V orlesungsNr] ⊆ V ORLESUNG[V orlesungsNr]<br />

F INDET ST AT T [V orlesungsNr] ⊆ V ORLESUNG[V orlesungsNr]<br />

F INDET ST AT T [RaumNr] ⊆ RAUM[RaumNr]<br />

1. Anfrage Gib die Bezeichnung <strong>der</strong> Vorlesung ’080104’.“<br />

”<br />

Die Daten zu Vorlesungen stehen in <strong>der</strong> Relation VORLESUNG. ’080104’ ist eine Vorlesungsnummer einer konkreten<br />

Vorlesung, also müssen wir diese konkrete Vorlesung selektieren. Wir interessieren uns nur für die Bezeichnung<br />

dieser Vorlesung, also müssen wir das Ergebnis auf das Attribut Bezeichnung projizieren:<br />

π Bezeichnung (σ V orlesungsNr= ′ 080104 ′(V ORLESUNG))<br />

<strong>2.</strong> Anfrage Gib die Namen aller Studenten, die die Veranstaltung ’080104’ hören, zusammen mit den Namen<br />

”<br />

aller Dozenten <strong>der</strong> Veranstaltung ’080104’.<br />

Die Daten <strong>der</strong> Studenten stehen in <strong>der</strong> Relation STUDENTEN, die Teilnahme in <strong>der</strong> Relation HOERT. Wenn<br />

wir aus HOERT die Tupel für die Veranstaltung ’080104’ selektieren, erhalten wir die Matrikelnummern <strong>der</strong> an<br />

’080104’ teilnehmenden Studenten. Wenn wir dieses Zwischenergebnis mit <strong>der</strong> Relation STUDENTEN verbinden<br />

und anschließend projizieren, erhalten wir die Namen dieser Studenten. Analog verfahren wir mit DOZENT und<br />

MITARBEITER. Beide Relationen zusammen bilden das Ergebnis <strong>der</strong> Anfrage.


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 19<br />

π Name ((σ V orlesungsNr= ′ 080104 ′(HOERT )) ⊲⊳ ST UDENT EN) ∪<br />

π Name ((σ V orlesungsNr= ′ 080104 ′(DOZENT )) ⊲⊳ MIT ARBEIT ER)<br />

3. Anfrage Angenommen, <strong>der</strong> Name identifiziert eine Person eindeutig. ”<br />

Gib die Personen, die Dozent einer<br />

Veranstaltung sind und sich parallel dazu für diese Veranstaltung als Student angemeldet haben.“<br />

Wir verbinden die DOZENT-Relation mit <strong>der</strong> MITARBEITER-Relation und projizieren anschließend auf die Attribute<br />

Name und VorlesungsNr, so bekommen wir die Namen <strong>der</strong> Dozenten einer Veranstaltung. Analog verfahren<br />

wir mit den eingeschriebenen Studenten. Der Durchschnitt bei<strong>der</strong> Mengen enthält die Personen, die gleichzeitig<br />

Dozent und Student einer Vorlesung sind.<br />

π Name,V orlesungsNr (DOZENT ⊲⊳ MIT ARBEIT ER) ∩<br />

π Name,V orlesungsNr (HOERT ⊲⊳ ST UDENT )<br />

4. Anfrage Finde Überschneidungen, d.h. gib die Namen <strong>der</strong> Studenten zusammen mit <strong>der</strong> entsprechenden Zeit<br />

”<br />

aus, so daß dieser Student zu diesem Zeitpunkt in zwei Räumen präsent sein muß.“<br />

Wir bilden für jeden Studenten Paare von Teilnahmen an Vorlesungsdurchführungen und verwerfen die Paare,<br />

<strong>der</strong>en Zeiten unterschiedlich sind. Teilnahmen an Vorlesungsdurchführungen erhalten wir durch das Verbinden <strong>der</strong><br />

Relationen HOERT und FINDETSTATT. Da Fremdschlüssel bzgl. <strong>der</strong> Relation VORLESUNG definiert sind, können<br />

wir die Relation VORLESUNG weglassen 2 . Wir benötigen das Attribut MatrikelNr aus HOERT und die Attribute<br />

Zeit und RaumNr aus FINDETSTATT. Wir führen diese Anfrage zweimal aus, beim zweiten mal benennen wir<br />

alle Attribute bis auf die Matrikelnummer um. Anschließend selektieren wir alle Tupel, <strong>der</strong>en Zeiten gleich, <strong>der</strong>en<br />

Räume aber verschieden sind. Diese Menge verbinden wir mit <strong>der</strong> STUDENT-Relation und projizieren alles außer<br />

dem Namen und <strong>der</strong> Zeit aus. π Name,Zeit (<br />

σ Zeit=Zeit2∧RaumNr!=RaumNr2 (<br />

π MatrikelNr,Zeit,RaumNr (HOERT ⊲⊳ F INDET ST AT T )<br />

⊲⊳<br />

(ϱ Zeit→Zeit2,RaumNr→RaumNr2 (<br />

π MatrikelNr,Zeit,RaumNr (HOERT ⊲⊳ F INDET ST AT T )<br />

))<br />

)<br />

⊲⊳<br />

STUDENT<br />

)<br />

5. Anfrage Gib die Studenten, die bei allen Dozenten eine Veranstaltung hören.“<br />

”<br />

Zunächst benötigen wir eine Zuordnung von Studenten (Matrikelnummern) zu Dozenten (Bearbeiternummer, Personalnummer).<br />

Anschließend teilen wir diese Relation durch die Relation mit allen Dozenten (Bearbeiternummer,<br />

Personalnummer) und erhalten das gewünschte Ergebnis.<br />

(π MatrikelNr,BearbeiterNr,P ersonalNr (HOERT ⊲⊳ DOZENT ))<br />

÷<br />

(π BearbeiterNr,P ersonalNr (DOZENT ))<br />

<strong>2.</strong><strong>2.</strong>2 Anfragen mit <strong>der</strong> Relationenalgebra<br />

• Abbildung Q DD : SAT (RS) −→ SAT (R)<br />

• universumstreu µ ∈ Q DD ∧ A ∈ R ⇒ µ(A) ∈ D DD<br />

2 Überlegen Sie sich, was passiert, wenn die Fremdschlüssel nicht definiert wären.


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 20<br />

• berechenbar - partiell rekursive Funktion<br />

• isomorphietreu - für <strong>Datenbanken</strong> M, M’ über Datenschemes DD, DD ′ und eine Bijektion von DD auf<br />

DD ′<br />

M<br />

h<br />

✲<br />

M ′<br />

Q<br />

❄<br />

Q(M)<br />

h<br />

✲<br />

Q<br />

❄<br />

h(Q(M)) = q(M ′ ) = Q(h(M))<br />

Damit: Querying Hypergraphen<br />

Beispiel aus dem Unibeispiel<br />

Bestimme für den Studenten “Alf Brummkopf” den Fachbereich seines Hauptfaches.<br />

Relationen:<br />

• Person = ({Name.First, Name.Fam, Name.Titel, Addr...., Personennummer} ,<br />

{ Personennummer}, ∅)<br />

• Student = ( { StudNr, Person.Personennummer, Hauptfach.Fachber.DName }, {StudNr},<br />

{ { Personennummer } −→ { StudNr } } )<br />

• sonstige Semantik: Student[Person.Personennummer] ⊆ Person[Personennummer] ...<br />

Damit kann dann die Anfrage im Hypergraphen direkt dargestellt werden.<br />

PERSON<br />

Name<br />

Adresse<br />

PNum<br />

Spezialis<br />

PROFESSOR<br />

SNum<br />

Hauptf<br />

Nebenf<br />

Betreuer<br />

STUDENT<br />

Kurs<br />

Semester<br />

Note<br />

TEILNAHME<br />

Zeit<br />

Raum<br />

VORLES<br />

Darstellung erfolgt nach Einführung <strong>der</strong> Algebra. Folgende Schritte führen zur korrekten Anfrage:<br />

1. Person P ersonennummer ✶ P erson.P ersonennummer Student<br />

<strong>2.</strong> σ Name.F irst=‘Alf ′ ∧Name.F am=‘Brummkopf ′ (Person P ersonennummer ✶ P erson.P ersonennummer Student)


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 21<br />

3. (σ Name.F irst=‘Alf ′ ∧Name.F am=‘Brummkopf ′ (Person)) P ersonennummer ✶ P erson.P ersonennummer Student<br />

4. π Hauptfach.F achber.DName ((σ Name.F irst=‘Alf ′ ∧Name.F am=‘Brummkopf ′<br />

(Person)) P ersonennummer ✶ P erson.P ersonennummer Student)<br />

5. π Hauptfach.F achber.DName (<br />

(σ Name.F irst=‘Alf ′ ∧Name.F am=‘Brummkopf ′ (Person))<br />

P ersonennummer ✶ P erson.P ersonennummer Student)<br />

6. π Hauptfach.F achber.DName (<br />

(σ Name.F irst=‘Alf ′ ∧Name.F am=‘Brummkopf ′ (<br />

π P ersonennummer,Name.F irst,Name.F am (Person))<br />

P ersonennummer ✶ P erson.P ersonennummer π P erson.P ersonennummer,Hauptfach.F achbereich.DName Student)<br />

Anfragen werden in einer Anfragesprache Q = L S1 ,S 2<br />

formuliert, die über Schemata S i definiert ist.<br />

Das Schema S 1 wird Input-Schema genannt, das Schema S 2 Output-Schema.<br />

Gegeben seien weiterhin die Menge Inst Si aller <strong>Datenbanken</strong> über S i .<br />

Wir können die Berechnung von Anfragen als Relation auffassen:<br />

RS Q 1 ,S 2<br />

= { (q, D 1 , D 2 ) | q ∈ Q ∧ D 1 ∈ Inst S1 ∧ D 2 ∈ Inst S2 }.<br />

Eine Funktion f : Q × Inst S1 → P(Inst S2 ) realisiert eine Relation R Q S 1 ,S 2<br />

falls für jedes q ∈ Q und jede<br />

Datenbank D 1 ∈ Inst S1 gilt, daß<br />

(1) falls kein y ∈ R Q S 1 ,DS 2<br />

existiert mit (x, D 1 , y) ∈ R Q S 1 ,S 2<br />

dann f(x) = λ und<br />

(2) f(x) = y für (x, D 1 , y) ∈ R Q S 1 ,S 2<br />

mit y ≠ λ.<br />

Eine Realisierung muß demzufolge nicht die Menge aller möglichen Resultate berechnen, son<strong>der</strong>n mindestens eines,<br />

falls es existiert.<br />

Eine Anfrage q ist in einer Anfragesprache Q über einem Schema S formuliert und liefert für eine Datenbank D<br />

über S ein o<strong>der</strong> mehrere Resultate.<br />

Demzufolge ist eine Anfrageanfor<strong>der</strong>ung eine spezifische Suchrelation definierbar:<br />

R Π = { (x, s) | x ∈ D Π ∧ s ∈ S Π (x) }.<br />

Eine Funktion f : Σ ∗ → Σ ∗ realisiert eine Relation R falls für jedes x ∈ Σ ∗ gilt, daß<br />

(1) falls kein y ∈ Σ + existiert mit (x, y) ∈ R dann f(x) = λ und<br />

(2) f(x) = y für (x, y) ∈ R mit y ≠ λ.<br />

Eine Anfrageanfor<strong>der</strong>ung besteht intentional aus zwei Komponenten:<br />

Suchkonzept: Ein Suchkonzept beschreibt die Suchanfor<strong>der</strong>ung. Wir haben dazu Anfrageformen eingeführt.<br />

Resultatkonzept: Ein Resultatkonzept beschreibt die Einbettung von Anfrageresultaten in ein Medienobjekt, das<br />

neben einem Tupelraum zur Aufnahme <strong>der</strong> Daten auch über eine eigenständige Repräsentation verfügt, sowie<br />

Strukturierungs- und Repräsentationsfunktionen.<br />

Die Forschung zur Datenbankanfrage-Unterstützung hat sogar eine allgemeinere Formulierung für Anfragen<br />

hervorgebracht, wie in Bild 1 illustriert.<br />

Der Zugang über Anfrage- und Antwortformen wird durch folgende Abbildungsvorschriften unterstützt:<br />

map : search concept ↦→ query form<br />

compile : (query form , database schema) ↦→ SQL query<br />

map : result concept ↦→ answer form<br />

process : SQL query ↦→ SQL answer set<br />

output : (SQL answer set , answer form) ↦→ answer to search<br />

Ziele einer Anfrageformulierung sind demzufolge:


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 22<br />

Datenbank<br />

schema<br />

<strong>DB</strong>MS-Anfrageinterface<br />

Suchanfor<strong>der</strong>ung<br />

✿<br />

Suchkonzept<br />

❄<br />

3 Resultatkonzept<br />

✲ Antwortform<br />

✲<br />

✛<br />

✲ Anfrageform<br />

❄<br />

SQLanfrage<br />

❄<br />

SQL-Antwortmenge<br />

❄ ✮<br />

Antwort<br />

auf Suche<br />

<br />

<strong>DB</strong>MS-Antwortrepräsentation<br />

Abbildung 1: Konzeptbasiertes Berechnen von Anfragen im klassischen Zugang und mit Anfrage- und Antwortformen<br />

Eingrenzung des Nichtdeterminismus: Jede Anfrage sollte so eindeutig wie nur möglich gestellt werden.<br />

Berechenbarkeit: Jede Anfrage sollte in eine Anfragevorschrift transformierbar sein, die ein Computer berechnen<br />

kann.<br />

Effektive Berechenbarkeit: Anfragen sollten auch in hinreichend kurzer Zeit bemessen am zu bewältigenden<br />

Datenumfang berechnet werden.<br />

Abbildung auf die Anfragesprache: Die Anfragen sollten in <strong>der</strong> zur Verfügung stehenden Anfragesprache formulierbar<br />

sein.<br />

Demzufolge ist die Formulierung einer Anfrage stets ein Vierschrittverfahren:<br />

1. Ergänzung <strong>der</strong> Anfrageäußerung zu einer genau formulierten Anfrage durch<br />

• Disambiguierung von Fragesätzen,<br />

• Ergänzung <strong>der</strong> Ellipsen zu vollständigen Sätzen,<br />

• Klärung, inwieweit eine Closed-World-Assumption o<strong>der</strong> eine partiell offene Datenwelt in <strong>der</strong> Datenbank<br />

unterlegt wird (Behandlung von Nullwerten) und<br />

• Schärfung <strong>der</strong> Formulierung von Aggregationsfunktionen;<br />

<strong>2.</strong> Reformulierung <strong>der</strong> Anfrage in eine existentiell geprägte Form wobei<br />

• nicht alle Generalisierungen aufgelöst werden müssen, son<strong>der</strong>n über ALL und ANY abgebildet werden<br />

können, und<br />

• ggf. auch besser überschaubare Boolesche Bedingungen erzeugt werden, indem z.B. die Negation<br />

möglichst weit zu den atomaren Formeln gezogen wird.<br />

3. Abbildung <strong>der</strong> Anfragebegriffe auf das Datenbank-Schema wobei ggf.<br />

• Spezifika <strong>der</strong> Schema-Definition mit beachtet werden wie z.B.<br />

• Nullwerte und Default-Werte, die eine Anfrageberechnung verän<strong>der</strong>n können, und<br />

• referentielle Inklusionsabhängigkeiten, die zur Verkürzung <strong>der</strong> Anfragepfade mit herangezogen<br />

werden können,<br />

• auch Hilfstabellen temporär für die Anfrage gebildet werden o<strong>der</strong> Sichten als Tabellen für eine ‘Nebenrechnung’<br />

bereitgestellt werden, sowie<br />

• eine Schrittfolge zur Berechnung <strong>der</strong> Resultate durch eine Prozedur bereitgestellt wird.<br />

4. Abbildung <strong>der</strong> Resultatskonzepte auf Antwortformen und Repräsentation dieser in SQL-Form.


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 23<br />

<strong>2.</strong><strong>2.</strong>3 Der generierende Kern <strong>der</strong> Relationenalgebra<br />

Da einige Operationen an<strong>der</strong>e ausdrücken können (z.B. gilt M ∩ N = M \ (M \ N)), können wir die Relationenalgebra<br />

einschränken auf die folgenden Operationen<br />

Projektion<br />

Umbenennung<br />

Verbund<br />

Vereinigung<br />

Differenz<br />

Selection<br />

Lemma 4 Der Theta-Verbund ist ausdrückbar durch Selektion und Verbund.<br />

R Aj Θ Bk R ′ = σ Aj ΘB k<br />

(R × R ′ )<br />

Proposition 1 Alle Operationen <strong>der</strong> Relationenalgebra sind ausdrückbar durch Ausdrücke über Relationennamen<br />

und den Operationen Projektion, Umbenennung, Verbund, Selektion, Vereinigung und Differenz.<br />

Corollary 1 Alle Operationen <strong>der</strong> Relationenalgebra sind ausdrückbar durch Ausdrücke über Relationennamen<br />

und den Operationen Projektion, Umbenennung, kartesisches Produkt, Selektion, Vereinigung und Differenz.<br />

<strong>2.</strong><strong>2.</strong>4 Sichten<br />

<strong>Relationale</strong> Sicht wird definiert durch Relationenschema V <strong>der</strong> Sicht (meist wird außerdem angenommen Σ V =<br />

∅) und einer Anfrage über einem relationalen Datenbankschema<br />

<strong>Relationale</strong> Sichtensuite wird definiert durch ein Datenbankschema mit relationalen Sichten<br />

Probleme:<br />

Modifikation <strong>der</strong> Grunddatenbank durch Sichten (Sichten-Update-Problem) [Bei Nichtidentifizierbarkeit von<br />

Objekten <strong>der</strong> Grunddatenbank durch eine Sicht, ist ein Modifikation <strong>der</strong> Datenbank verboten. Dieses Problem<br />

kann gelöst werden durch separate Modifikationssichten neben den Retrievalsichten, die durch Hilfssichten<br />

miteinan<strong>der</strong> und mit <strong>der</strong> Grunddatenbank gekoppelt werden.]<br />

Virtualisierung o<strong>der</strong> Materialisierung von Sichten ohne o<strong>der</strong> mit Kollaborationsvertrag<br />

<strong>2.</strong><strong>2.</strong>5 Eine bessere mathematische Grundlage <strong>der</strong> relationalen Algebra<br />

Der folgende Teil zeigt, daß auch die Väter des relationalen Modelles nicht allzu viel von Mathematik verstanden<br />

und deshalb auch die falsche Welt erfunden haben. Erstaunlich ist, wie überlebensfähig die unmathematischen<br />

Denkweisen sind und wie gut trotzdem die <strong>Technologie</strong>n geworden sind.<br />

“Die Vater” und nicht <strong>der</strong> ‘Vater’, weil nicht die Arbeit<br />

E. F. Codd A Relational Model of Data for Large Shared Data Banks. Commun. ACM., 13 (6): pp. 377-387, 1970<br />

son<strong>der</strong>n die (Codd durchaus sehr gut bekannte) Arbeit<br />

D. L. Childs, Feasibility of a set-theoretical data structure - a general structure based on a reconstituted definition of relation. Proc. IFIP Cong., North Holland Pub. Co., Amsterdam, pp. 162-17<strong>2.</strong>, 1968<br />

das relationale Modell eingeführt hat.<br />

Zylindrische Algebren (Henkin 1985) R C ∨ S C , ∼ R C , R C [X] = π X (R C ), D i,j (R C ) = σ i=j (R C )<br />

Explizite Mitführung des Hea<strong>der</strong>s R einer Relation R C (wie wir dies bereits für die Operationen vorn betrachtet<br />

haben) erlaubt die Einführung folgen<strong>der</strong> Operationen und Prädikate


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 24<br />

• Projektion: wie üblich<br />

• Teiltyp: (R, R C ) ⊑ (S, S C ) falls R ⊇ S und π S (R C ) ⊆ S C<br />

• dem natürlichen Verbund ⊗ als “meet”-Operation o<strong>der</strong> infimum-Operation mit<br />

(R, R C ) ⊗ (S, S C ) := (R ∪ S, R C ✶ S C )<br />

• <strong>der</strong> inneren Summe ⊕ als “join”-Operation als supremum-Operation<br />

(R, R C ) ⊕ (S, S C ) := (R ∩ S, π R∩S (R C ) ∪ π R∩S (S C ))<br />

Die Operationen ⊗ und ⊕ sind idempotent, kommutative und assoziativ. Sie erfüllen auch das Adsorptionsgesetz<br />

R C ⊗ (R C ⊕ S C ) = R C<br />

R C ⊕ (R C ⊗ S C ) = R C .<br />

Die Teiltyprelation führt direkt auf einen (nicht-distributiven, modularen) relationalen Verband<br />

• mit einem maximalen Element ⊤ := (∅, ∅)<br />

• dem minimalen Element ⊥ := (U, ∅)<br />

• ⊗ und ⊕ sind die infimum- und supremum-Operationen des Verbandes für die partielle Ordnung<br />

• partiellen Distributivitätsgesetzen, bei denen die Übereinstimmung <strong>der</strong> hea<strong>der</strong> gefor<strong>der</strong>t werden muß<br />

(R, R C ) ⊗ ((S, S C ) ⊕ (T, T C )) = ((R, R C ) ⊗ (S, S C )) ⊕ ((R, R C ) ⊗ (T, T C ))<br />

mit <strong>der</strong> Einschränkung R ∩ S = R ∩ T<br />

(R, R C ) ⊕ ((S, S C ) ⊗ (T, T C )) = ((R, R C ) ⊕ (S, S C )) ⊗ ((R, R C ) ⊕ (T, T C ))<br />

mit <strong>der</strong> Einschränkung R ∩ S = R ∩ T = S ∩ T<br />

Führt man explizit auch die Zylin<strong>der</strong>algebra-Operationen<br />

• die Diagonale D A,B = {(a, b) ∈ Dom(A) × Dom(B)|a = b} und<br />

• die Entleeruung (R, R C ) ∅ := (R, ∅)<br />

mit ein, dann kann man alle Operationen <strong>der</strong> relationalen Algebra ausdrücken:<br />

• Selektion σ A=B (R C ) durch (R, R C ) ⊗ D A,B<br />

• Projektion π X (R C ) durch (R, R C ) ⊕ (X, ∅)<br />

• Join durch ⊗<br />

• Umbenennung ρ A↦→B (R C ) durch ((R, R C ) ⊗ D A,B ) ⊕ (R \ {A} ∪ {B}, ∅)<br />

• Vereinigung direkt für gleiche hea<strong>der</strong><br />

<strong>2.</strong>3 Der relationale Kalkül / Relationenkalkül / Tupelkalkül<br />

<strong>2.</strong>3.1 Der Relationenkalkül<br />

Relationenalgebra und Relationenkalkül<br />

zwei verschiedene Anfragesprachen<br />

relationale Anfragesprache: formale Sprache L, die für jeden Ausdruck angewandt auf eine Relation wie<strong>der</strong>um<br />

eine Relation liefert<br />

i.a. endliche Relation<br />

2 Arten<br />

Relationenalgebra natürlicher Verbund, Vereinigung, Selektion, Projektion, Vergleich, Komplement<br />

Relationenkalkül Sprache <strong>der</strong> Prädikatenlogik


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 25<br />

Ausdrücke <strong>der</strong> relationalen Algebra definiert über<br />

• R i ∈ L Al<br />

type(R i ) = R i<br />

• T ✶ T ′ ∈ L Al type(T ✶ T ′ ) = type(T ) ∪ type(T ′ )<br />

• T + T ′ ∈ L Al type(T ✶ T ′ ) = type(T ) ∪ type(T ′ )<br />

• π η (T ) ∈ L Al type(η) = T ′ , type(π η (T )) = T ′<br />

• σ A=B (T ) ∈ L Al type(σ A=B ) = type(T )<br />

• σ A≠B (T ) ∈ L Al type(σ A=B (T )) = type(T )<br />

• γ(T ) = D T DD \ T ∈ L Al type(γ(T )) = type(T )<br />

Diese Sprache ist nicht sicher, falls man die Endlichkeit von Relationen voraussetzt.<br />

Analog läßt sich eine sichere Algebra aufbauen:<br />

• Selektionsausdrücke<br />

• Join, Projektion, Umbennenung, (Vereinigung,) Differenz<br />

Semantik bei<strong>der</strong> Sprachen in <strong>der</strong> üblichen Art definiert<br />

Definition <strong>der</strong> Auswertungsfunktion eval<br />

siehe Semantik von PS<br />

Eigenschaften<br />

1. Jede Anfrage <strong>der</strong> relationalen Algebra ist eine Anfrage im Sinne <strong>der</strong> obigen Definition.<br />

<strong>2.</strong> Die sichere Algebra ist nicht isomorphietreu (σ A=c ).<br />

3. Die transitive Hülle ist mit keiner von beiden Algebren berechenbar.<br />

R = {A, B}, (R C ) ∗ = {(a, b)|∃a 1 , ..., a k : (a, a 1 ), (a 1 , a 2 ), ...(a k−1 , a k ), (a k , b) ∈ R C }<br />

Beweis über die Nichtexistenz eines Ausdruck, mit dem (R C ) ∗ berechnet werden kann. Ausdrückbar ist: es<br />

gibt einen Weg <strong>der</strong> fixierten Länge n.<br />

Mit logischen Modellen aussdrückbar.<br />

4. Eine Anfrage e(db) ist in L Al genau dann definierbar, wenn sie invariant geüber allen Automorphismen<br />

vondb ist.<br />

Relationenkalkül 3 (Attributkalkül (Variable Attributen zuordnet (tupelwertige Kalüle sind analog))<br />

• P Ri (v i,1 , ..., v i,ni ), v i,j Variable vom Typ A j für R i = {A 1 , ..., A ni } und Ordnung über R i<br />

kurz: R i (v i,1 , ..., v i,ni )<br />

• α ◦ β, ◦ ∈ {∨, ∧}<br />

• ¬α<br />

3 Der Tupelkalkül ist eine <strong>der</strong> Verirrungen <strong>der</strong> Datenbankforschung. Man hat brute-force den Prädikatenkalkül genutzt. Lei<strong>der</strong> wurde<br />

dabei übersehen, daß endliche Mengen an<strong>der</strong>e Kalküle erfor<strong>der</strong>n und sich dann extensiv bemüht mit vielen Begriffen, die Anfangsfehler<br />

algorithmisch o<strong>der</strong> zumindest begrifflich für die Konstruktionen auszumerzen. Ein an<strong>der</strong>es solches Beispiel ist auch die Definition des Begriffes<br />

“dependency”, die heute kaum noch jemand so nutzt, son<strong>der</strong>n nur für die speziellen Klassen.<br />

Diese Situation ist typisch für viele Entwicklungen in <strong>der</strong> Informatik: Erst unglücklich anstellen bei <strong>der</strong> Definition und dann Generationen<br />

von Forschern verbraten mit <strong>der</strong> Reparatur. Brute-force-Entwicklungen ohne Verständnis des Gegenstandes führen meist zu Verirrungen<br />

und aufwendigen Reparaturmaßnahmen. XML wie<strong>der</strong>holt gerade diese Geschichte. Gestartet als extrem einfaches und wun<strong>der</strong>volles Austauschformat<br />

und dort extrem nützlich und nun mittlerweile als volle Programmier- und Darstellungssprache mit einem Wirrwarr, das man<br />

kaum übertreffen kann.<br />

Frei nach H. Thiele: Definitionen sind Glücksache. Und Glück haben nur wenige.


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 26<br />

• ∃v α,<br />

∀v α<br />

Der Relationenkalkül kann elegant eingeführt werden in Verallgemeinerung von Atzeni/Ceri/Paraboschi/Torlone<br />

als Tripel<br />

{target structure | context | conditions}<br />

Damit kann man z.B. auch XML-Abhängigkeiten elegant formulieren, wie Link und Hartmann zeigten. Ursprünglich<br />

verwendeten Atzeni/Ceri/Paraboschi/Torlone das Tripel<br />

{target structure | C | conditions}<br />

für den Bereich (range) [context] C.<br />

Diese Struktur ist elegant direkt mit SQL verbindbar sowie auch <strong>der</strong> relationalen Algebra .<br />

Der “algebraische” Relationenkalkül ist besser einführbar nach Thalheim (Teubner 1991) durch:<br />

{t | R | 1} for each relation schema R<br />

{t | C | β}<br />

{t | C | β ∧ α}<br />

{t 1 | C 1 | α 1 } , {t 2 | C 2 | α 2 }<br />

{t 1 ✶ t 2 | C 1 ∪ C 2 | α 1 ∧ α 2 }<br />

{t | C | α 1 } , {t | C | α 2 }<br />

{t | C | α 1 ∨ α 2 }<br />

{t | C | α 1 } , {t | C | α 2 }<br />

{t | C | α 1 ∧ ¬α 2 }<br />

{t | C | α}<br />

{ρ(t) | C | α}<br />

{t | C | α}<br />

{π X (t) | C | α}<br />

<strong>2.</strong>3.2 Syntax des relationalen Tupelkalküls<br />

4<br />

for selection σ α<br />

for join ✶<br />

for union ∪<br />

for set difference \<br />

for renaming ρ<br />

for projection π X<br />

Der relationale Tupelkalkül (engl. tuple relational calculus, TRC) ist eine Anfragesprache für relationale <strong>Datenbanken</strong>,<br />

die Ausdrücke <strong>der</strong> Prädikatenlogik erster Stufe benutzt, um das gewünschte Ergebnis einer Anfrage zu<br />

beschreiben. Eine mögliche Anfrage an das Vorlesungs- und Studentenbeispiel aus dem Übungsskript zur relationalen<br />

Algebra könnte z.B. sein:<br />

Gib die Namen und Matrikelnummern <strong>der</strong> Studenten, die eine Vorlesung hören, die von einem Dozenten namens<br />

Meyer gehalten wird.<br />

Wer die relationale Algebra benutzt, muß eine Operationsfolge angeben, die das Ergebnis aus den Relationen<br />

<strong>der</strong> Datenbank konstruiert. Die Anfrage ist aber eigentlich an<strong>der</strong>s formuliert: die gesuchten Studenten werden durch<br />

die sie charakterisierenden Eigenschaften beschrieben, nämlich die Eigenschaft, daß sie bestimmte Vorlesungen<br />

hören. Diese Vorlesungen sind dadurch charakterisiert, daß sie von einem bestimmten Dozenten (mit dem Namen<br />

Meyer) gehalten werden. Der TRC versucht, diese Charakterisierung auf einem formalen Wege durchzuführen.<br />

Sei ein Datenbankschema D gegeben. Wir definieren eine Menge von Variablen. In den folgenden Ausführungen<br />

werden wir Variablen mit kleinen lateinischen Buchstaben schreiben. Die Variablen stellen Platzhalter für<br />

4 Dieser Teil des Skriptum wurde von G. Fiedler (mein Dank dafür) erstellt.<br />

Wir empfehlen trotz <strong>der</strong> obigen Bemerkung das Studium des Tupelkalkül, weil die in <strong>der</strong> Datenbanktechnologie übliche Mengenverarbeitung<br />

dem in <strong>der</strong> sequentiellen Programmierung erprobten Informatiker etwas ungebräuchlich ist. Meist fällt dem Anfänger eine Anfrageformulierung<br />

mit dem TRC leichter, man sollte aber über die Probleme und die schwierige Behandlung sich im Klaren sein.


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 27<br />

Tupel dar. Je<strong>der</strong> Variablen ist ein Typ zugeordnet: seien A 1 , ..., A n die Attribute über denen die Tupel, die <strong>der</strong><br />

Variable später zugeordnet werden sollen, definiert sind. Dann ist die Menge {A 1 , ..., A n } <strong>der</strong> Typ <strong>der</strong> Variable.<br />

Den Typ einer Variablen, z.B. <strong>der</strong> Variablen x, bezeichnen wir mit type(x).<br />

In unserem Beispiel suchen wir z.B. die Namen und die Matrikelnummern <strong>der</strong> Studenten. Deshalb können wir<br />

z.B. einen Typ type(x) = {MatrikelNr, Name} einführen. Die Variable x ist jetzt Platzhalter für Tupel über<br />

MatrikelNr und Name.<br />

Eine Anfrage des TRC ist eine prädikatenlogische Formel (erster Stufe) <strong>der</strong> folgenden Form:<br />

• Wenn R ein Relationenschema in D und x eine Variable mit type(x) = attr(R) ist, dann ist R(x) eine<br />

Formel im Sinne des TRC mit x als freier Variablen.<br />

Beispiele:<br />

ST UDENT (y) mit type(y) = {MatrikelNr, Name, W ohnort}<br />

RAUM(z) mit type(z) = {RaumNr, Bezeichnung}<br />

• Wenn x und y Variablen, A ∈ type(x) und B ∈ type(y) Attribute und ⊙ ein Prädikat über den Typen von<br />

A und B ist, dann ist x.A ⊙ y.B eine Formel im Sinne des TRC mit den freien Variablen x und y. Analog<br />

wird <strong>der</strong> Vergleich mit Konstanten definiert.<br />

Beispiele:<br />

y.W ohnort = ′ Kiel ′<br />

x.Name = y.Name<br />

• Wenn ϕ und ψ Formeln im Sinne des TRC sind, dann sind auch die aussagenlogischen Verknüpfungen von<br />

ϕ und ψ Formeln im Sinne des TRC. Die freien Variablen entsprechen denen <strong>der</strong> Formeln ϕ und ψ.<br />

Beispiele:<br />

y.W ohnort = ′ Kiel ′ ∧ x.Name = y.Name<br />

x.Name = ′ P etersen ′ =⇒ y.Name = ′ Schmidt ′<br />

• Wenn ϕ eine Formel im Sinne des TRC und x eine freie Variable in ϕ ist, dann sind auch<br />

(∀x)(ϕ)<br />

(∃x)(ϕ)<br />

Formeln des TRC. Die freien Variablen dieser Formeln entsprechen den freien Variablen von ϕ ohne x.<br />

Beispiel:<br />

(∀v)(V ORLESUNG(v) =⇒ (∃f)(F INDET ST AT T (f) ∧ f.V orlesungsNr = v.V orlesungsNr))<br />

Erste Semantikdefinition des TRC.<br />

Im Übungsskript “Grundlagen <strong>der</strong> Logik” wurde <strong>der</strong> Begriff des Modells für eine Formel ϕ <strong>der</strong> Prädikatenlogik<br />

erster Stufe eingeführt. Wir gehen in dieser Diskussion von gegebenen Wertebereichen und einer festen (und<br />

trivialen) Belegung <strong>der</strong> Konstantensymbole aus, deshalb sind wir an Paaren I, ϱ interessiert, die unsere Formel ϕ<br />

wahr werden lassen.<br />

Die Interpretation I ordnet den Prädikaten eine Ausprägung zu, also die Menge von Tupeln, für die das Prädikat<br />

zu wahr ausgewertet wird. Im TRC betrachten wir 2 verschiedene Arten von Prädikaten:<br />

1. R(x) für ein Relationenschema R,


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 28<br />

<strong>2.</strong> ⊙, definiert auf Ebene <strong>der</strong> Datentypen.<br />

Es liegt nahe, die Ausprägung <strong>der</strong> Prädikate <strong>der</strong> ersten Art an die Relationen unserer Datenbank zu binden.<br />

Für die Prädikate <strong>der</strong> zweiten Art benutzen wir die Definitionen <strong>der</strong> Prädikate in den Datentypen. Da wir diese<br />

Definition als konstant ansehen, werden wir in <strong>der</strong> weiteren Diskussion nur noch die Prädikate <strong>der</strong> ersten Art<br />

betrachten.<br />

Als Interpretation benutzen wir demnach einen ( ”<br />

den aktuellen“) Zustand σ(D) zu unserem Datenbankschema<br />

D. Als Ergebnis einer TRC-Anfrage bezeichnen wir die Menge <strong>der</strong> Variablenbelegungen ϱ, so daß<br />

σ(D), ϱ |= ϕ<br />

Da i.d.R. nicht die Belegungen aller Variablen interessant sind, wird pro Antwort auf die Anfrage ϕ nur die<br />

Belegung <strong>der</strong> freien Variablen in ϕ angegeben. Um auch dies weiter einzuschränken, kann man vor die Formel<br />

ϕ eine Projektionsliste mit den gewünschten Attributen schreiben. Seien x 1 , ..., x k die freien Variablen in ϕ und<br />

A 1 , ..., A l Attribute in den Typen von x 1 , ..., x k , dann kann man schreiben:<br />

x 1 .A 1 , ..., x i .A j<br />

Diese Schreibweise konstruiert Tupel über {A 1 , ..., A j } als Ergebnis <strong>der</strong> Anfrage.<br />

Beispiel: ”<br />

Gib die Namen und Matrikelnummern aller Kieler Studenten zusammen mit den Veranstaltungsnummern,<br />

so daß dieser Student diese Veranstaltung mindestens in <strong>der</strong> ersten Wie<strong>der</strong>holung hört.“<br />

s.Name, s.MatrikelNr, h.V orlesungsNr | ST UDENT (s) ∧ HOERT (h)∧<br />

h.MatrikelNr = s.MatrikelNr ∧ h.W ie<strong>der</strong>holung ≥ 1<br />

Wenn die Menge <strong>der</strong> freien Variablen <strong>der</strong> Formel ϕ leer ist (d.h. alle Variablen in ϕ sind an Quantoren gebunden),<br />

dann ist die Antwort entwe<strong>der</strong> ja (d.h. σ(D) |= ϕ) o<strong>der</strong> nein (d.h. σ(D) ϕ).<br />

Selbststudium Führen Sie sich anhand <strong>der</strong> folgenden Semantikdefinition vor Augen, daß die Variablenbelegung<br />

ϱ in diesem Falle für die Erfüllbarkeit keine Rolle spielt. Führen Sie sich weiterhin vor Augen, daß die Projektion<br />

auf die gewünschten Attribute nur syntaktischer Zucker“ ist.<br />

”<br />

Nachdem wir festgelegt haben, welche Attribute als Antwort auf die Anfrage auszugeben sind, können wir eine<br />

erste Semantikdefinition des TRC angeben. Sei ϱ eine Variablenbelegung:<br />

1. Sei R ein Relationenschema und x eine Variable, dann gilt σ(D), ϱ |= R(x) gdw. ϱ(x) ∈ σ(R), d.h. das<br />

Tupel, mit dem x belegt ist, ist in <strong>der</strong> zu R gehörenden Relation enthalten.<br />

<strong>2.</strong> σ(D), ϱ |= x.A ⊙ y.B gdw. ⊙(ϱ(x)(A), ϱ(y)(B)), d.h. wir betrachten die Tupel, mit denen die Variablen<br />

x und y belegt sind. Wenn das Prädikat ⊙ auf die Werte <strong>der</strong> Attribute A und B dieser Tupel angewendet<br />

wird, muß es wahr ergeben, damit <strong>der</strong> Datenbankzustand und die Variablenbelegung ein Modell bilden.<br />

Vergleiche mit Konstanten werden analog behandelt.<br />

3. σ(D), ϱ |= ϕ ∧ ψ für zwei Formeln ϕ und ψ gdw. σ(D), ϱ |= ϕ und σ(D), ϱ |= ψ. Die an<strong>der</strong>en aussagenlogischen<br />

Verknüpfungen werden analog behandelt.<br />

4. σ(D), ϱ |= (∃x)(ϕ), gdw. es eine Variablenbelegung ϱ ′ gibt, so daß sich ϱ ′ von ϱ höchstens in <strong>der</strong> Belegung<br />

von x unterscheidet und σ(D), ϱ ′ |= ϕ gilt.<br />

5. σ(D), ϱ |= (∀x)(ϕ), gdw. für alle Variablenbelegungen ϱ ′ , die sich von ϱ höchstens in <strong>der</strong> Belegung von x<br />

unterscheiden, gilt, daß σ(D), ϱ ′ |= ϕ.<br />

| ϕ<br />

Auswertung einer Anfrage.<br />

Es sei <strong>der</strong> folgende Zustand gegeben (es sind nur die relevanten Relationen angegeben):


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 29<br />

STUDENT<br />

MatrikelNr Name Wohnort<br />

190245 Max Müller Kiel<br />

327641 Tina Petersen Flensburg<br />

612491 Tobias Schulze Kiel<br />

762198 Uwe Schmidt Rendsburg<br />

VORLESUNG<br />

VorlesungsNr<br />

Bezeichnung<br />

080104 SysInf IV<br />

080016 Info IV<br />

080127 Info II<br />

080176 SysInf II<br />

HOERT<br />

MatrikelNr VorlesungsNr Wie<strong>der</strong>holung<br />

190245 080104 0<br />

190245 080016 0<br />

327641 080127 0<br />

327641 080176 0<br />

612491 080104 0<br />

612491 080016 0<br />

612491 080127 1<br />

612491 080176 1<br />

762198 080104 2<br />

Betrachten wir obige Anfrage<br />

s.Name, s.MatrikelNr, h.V orlesungsNr | ST UDENT (s) ∧ HOERT (h)∧<br />

h.MatrikelNr = s.MatrikelNr ∧ h.W ie<strong>der</strong>holung ≥ 1<br />

Wir müssen nun für alle beliebigen Variablenbelegungen prüfen, ob <strong>der</strong> Datenbankzustand und die Belegung<br />

ein Modell <strong>der</strong> Anfrage bilden. Die möglichen Variablenbelegungen ergeben sich aus den Wertebereichen <strong>der</strong><br />

Attribute:<br />

type(s) = {MatrikelNr, Name, W ohnort}<br />

type(h) = {MatrikelNr, V orlesungsNr, W ie<strong>der</strong>holung}<br />

Die Belegungen <strong>der</strong> Variablen s bestehen demnach aus allen Kombinationen möglicher Matrikelnummern, Namen<br />

und Wohnorte. Wenn wir davon ausgehen, daß alle drei Attribute über dem Datentyp ”<br />

Zeichenkette“ definiert<br />

sind, müssen wir alle Kombinationen aus drei beliebigen und beliebig langen Zeichenketten betrachten. Damit<br />

ergeben sich z.B. folgende Belegungen:


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 30<br />

ρ(s) MatrikelNr Name Wohnort<br />

000000 a a<br />

000001 a a<br />

000002 a a<br />

... ... ...<br />

190245 Max Müller Kiel<br />

190245 Max Müller Lübeck<br />

190245 Max Müller Flensburg<br />

... ... ...<br />

327641 Tina Petersen Flensburg<br />

327641 Max Müller Flensburg<br />

327641 Max Müller aW349(3!<br />

... ... ...<br />

zsafhgsadz HTjhsbva,! OiEwiuq43D<br />

... ... ...<br />

Es ist leicht ersichtlich, daß es unendlich viele Kombinationen dreier (beliebig langer) Zeichenketten gibt. Eine<br />

analoge Diskussion kann für die Belegung <strong>der</strong> Variablen h erfolgen. Durch scharfes Hinsehen“ 5 stellen wir aber<br />

”<br />

fest, daß für alle Belegungen, die s kein Tupel aus <strong>der</strong> Relation ST UDENT zuweisen, die gesamte Formel niemals<br />

erfüllt werden kann. Analog wird die Formel nur erfüllt, wenn <strong>der</strong> Variablen h ein Tupel aus <strong>der</strong> Relation HOERT<br />

zugeordnet wird. Die letzten beiden Bedingungen schränken dies weiter ein: es werden alle Kombinationen aus s<br />

und h verworfen, die die beiden Vergleiche nicht erfüllen. Es bleiben die folgenden Belegungen übrig:<br />

s<br />

ϱ 1<br />

MatrikelNr Name Wohnort<br />

612491 Tobias Schulze Kiel<br />

ϱ 2<br />

MatrikelNr Name Wohnort<br />

612491 Tobias Schulze Kiel<br />

ϱ 3<br />

MatrikelNr Name Wohnort<br />

762198 Uwe Schmidt Rendsburg<br />

h<br />

MatrikelNr VorlesungsNr Wie<strong>der</strong>holung<br />

612491 080127 1<br />

MatrikelNr VorlesungsNr Wie<strong>der</strong>holung<br />

612491 080176 1<br />

MatrikelNr VorlesungsNr Wie<strong>der</strong>holung<br />

762198 080104 2<br />

Diese projizieren wir auf die gegebenen Attribute und erhalten unsere Antwort:<br />

Name MatrikelNr VorlesungsNr<br />

Tobias Schulze 612491 080127<br />

Tobias Schulze 612491 080176<br />

Uwe Schmidt 762198 080104<br />

Betrachten wir weiterhin folgende Anfrage (type(x) = attr(V ORLESUNG)):<br />

¬V ORLESUNG(x)<br />

Auch hier müssen wir alle Tupel betrachten, die sich aus zwei beliebig langen Zeichenketten (VorlesungsNr und<br />

Bezeichnung) bilden lassen. Durch ”<br />

scharfes Hinsehen“ stellen wir fest, daß sich die vier im Zustand <strong>der</strong> Datenbank<br />

aufgeschriebenen Tupel nicht für die Antwort qualifizieren. Jede an<strong>der</strong>e Kombination aus einer Zeichenkette für die<br />

Vorlesungsnummer und die Bezeichnung — auch alle unsinnigen Kombinationen — sind Teil <strong>der</strong> Antwortmenge.<br />

Da es unendlich viele solche Kombinationen gibt, dauert es unendlich lange, bis die Antwort berechnet ist. Mit<br />

an<strong>der</strong>en Worten ausgedrückt: unser Algorithmus terminiert nicht, das Ergebnis <strong>der</strong> Anfrage ist nicht berechenbar.<br />

Ausdrücke dieser Form nennen wir in Zukunft ”<br />

unsichere Ausdrücke“ (da man sich, vereinfacht gesprochen, nicht<br />

sicher sein kann, ein Ergebnis zu erhalten.) Ausdrücke, die stets eine endliche Menge von Ergebnistupeln liefern,<br />

nennen wir ”<br />

sichere Ausdrücke“. ”<br />

Stets“ bedeutet in diesem Zusammenhang, daß die Endlichkeit des Ergebnisses<br />

für alle gültigen Datenbankzustände garantiert ist.<br />

Sicherheit und Wertebereichsunabhängigkeit.<br />

5 Systematischere Verfahren lernen Sie in <strong>der</strong> Veranstaltung ”<br />

Datenbanktheorie“ o<strong>der</strong> in <strong>der</strong> Logikprogrammierung kennen.


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 31<br />

Die Menge <strong>der</strong> sicheren TRC-Ausdrücke ist unentscheidbar, d.h. es gibt keinen Algorithmus, <strong>der</strong> für einen<br />

beliebigen gegebenen TRC-Ausdruck bestimmt, ob dieser sicher o<strong>der</strong> unsicher ist. Aus diesem Grunde betrachtet<br />

man eine weitere Eigenschaft: die Wertebereichsabhängigkeit bzw. -unabhängigkeit eines TRC-Ausdrucks.<br />

Das Problem <strong>der</strong> unsicheren TRC-Ausdrücke liegt in <strong>der</strong> Tatsache begründet, daß über einem unendlichen<br />

Wertebereich gearbeitet wird und sich prinzipiell jedes Tupel dieser unendlichen Menge für das Ergebnis qualifizieren<br />

kann. Unsinnige Wertekombinationen in Tupeln <strong>der</strong> Antwort (z.B. die Vorlesungsbezeichnung lhiGf!r5W )<br />

interessieren uns aber eigentlich nicht. Deshalb können wir untersuchen, was passiert, wenn wir nicht mehr alle<br />

beliebigen Belegungen unserer Variablen betrachten, son<strong>der</strong>n nur noch die Belegungen, <strong>der</strong>en (Attribut-)Werte auf<br />

irgendeine Art und Weise im Datenbankzustand o<strong>der</strong> in <strong>der</strong> Anfrage vorkommen, die wir also als ”<br />

sinnvoll“ erachten.<br />

Wenn eine Anfrage jetzt eine an<strong>der</strong>e Antwort liefert als im vorher diskutierten Fall, dann hängt das Ergebnis<br />

nicht nur vom Datenbankzustand ab, son<strong>der</strong>n von den Werten <strong>der</strong> Wertebereiche <strong>der</strong> Attribute. In diesem Fall sprechen<br />

wir von einem wertebereichsabhängigen TRC-Ausdruck. Wenn sich das Ergebnis nicht verän<strong>der</strong>t, dann ist <strong>der</strong><br />

TRC-Ausdruck wertebereichsunabhängig. Die erste Anfrage im Abschnitt <strong>2.</strong>3.2 ist eine wertebereichsunabhängige<br />

Anfrage: Egal welche Wertebereiche wir betrachten 6 , die Anfrage liefert bzgl. eines fest gewählten Datenbankzustands<br />

immer die gleiche Antwort. Die zweite Anfrage (¬V ORLESUNG(x)) ist wertebereichsabhängig, denn<br />

z.B. je nach den möglichen Vorlesungsbezeichnungen entsteht jedesmal eine an<strong>der</strong>e Antwort.<br />

Es gilt: Je<strong>der</strong> wertebereichsunabhängige TRC-Ausdruck ist sicher. Die Umkehrung muß nicht zwangsläufig<br />

gelten 7 . Lei<strong>der</strong> ist die Menge <strong>der</strong> wertebereichsunabhängigen Ausdrücke immer noch unentscheidbar. Um eine<br />

Entscheidbarkeit zu erzwingen, werden die vom System zugelassenen Anfragen syntaktisch eingeschränkt, d.h.<br />

wir erlauben nicht mehr beliebige Anfragen des TRC. Dies führt uns zur Definition <strong>der</strong> erlaubten Ausdrücke.<br />

Erlaubter TRC-Ausdruck In einem erlaubten TRC-Ausdruck wird jede Variable an den Datenbankzustand gebunden“.<br />

Um dies festzustellen, prüfen wir für jedes Attribut A je<strong>der</strong> Variablen x, ob das Paar (x, A) in einem ”<br />

Ausdruck ϕ positiv o<strong>der</strong> negativ beschränkt ist:<br />

1. (x, A) ist positiv beschränkt in R(x)<br />

<strong>2.</strong> Sei c eine Konstante. Dann ist (x, A) positiv beschränkt in x.A = c und c = x.A. Wir setzen die übliche<br />

Definition des Gleichheitsprädikats voraus.<br />

3. (x, A) ist positiv beschränkt in x.A = y.B bzw. y.B = x.A, wenn <strong>der</strong> Term Teil einer Konjunktion ist<br />

(F 1 ∧ ... ∧ x.A = y.B ∧ ... ∧ F n ), in <strong>der</strong> y.B positiv beschränkt ist.<br />

4. (x, A) ist positiv beschränkt in ¬ϕ, wenn (x, A) negativ beschränkt ist in ϕ.<br />

5. (x, A) ist positiv beschränkt in ϕ ∧ ψ, falls (x, A) positiv beschränkt ist in ϕ o<strong>der</strong> in ψ.<br />

6. (x, A) ist positiv beschränkt in ϕ ∨ ψ, falls (x, A) positiv beschränkt ist in ϕ und in ψ.<br />

7. (x, A) ist positiv beschränkt in ϕ =⇒ ψ, falls (x, A) negativ beschränkt ist in ϕ und positiv beschränkt in<br />

ψ.<br />

8. (x, A) ist positiv beschränkt in (∃y)(ϕ) o<strong>der</strong> in (∀y)(ϕ), falls (x, A) positiv beschränkt ist in ϕ.<br />

9. (x, A) ist negativ beschränkt in ¬ϕ, falls (x, A) positiv beschränkt ist in ϕ.<br />

10. (x, A) ist negativ beschränkt in ϕ ∧ ψ, falls (x, A) negativ beschränkt ist in ϕ und in ψ.<br />

11. (x, A) ist negativ beschränkt in ϕ ∨ ψ, falls (x, A) negativ beschränkt ist in ϕ o<strong>der</strong> in ψ.<br />

1<strong>2.</strong> (x, A) ist negativ beschränkt in ϕ =⇒ ψ, falls (x, A) positiv beschränkt ist in ϕ o<strong>der</strong> negativ beschränkt in<br />

ψ.<br />

6 Die Werte des Datenbankzustands müssen natürlich in den Wertebereichen enthalten sein, sonst wi<strong>der</strong>spricht dies unseren Definitionen<br />

des relationalen Modells!<br />

7 Wenn man z.B. nur endliche Wertebereiche betrachtet, dann ist je<strong>der</strong> Ausdruck sicher. Er kann aber sehr wohl wertebereichsabhängig<br />

sein.


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 32<br />

13. (x, A) ist negativ beschränkt in (∃y)(ϕ) o<strong>der</strong> in (∀y)(ϕ), falls (x, A) negativ beschränkt ist in ϕ.<br />

Eine Variable x ist positiv (negativ) beschränkt in einem Ausdruck ϕ, falls die positive (negative) Beschränkung<br />

für alle Attribute dieser Variablen gilt.<br />

Ein TRC-Ausdruck ϕ heißt erlaubt, wenn folgendes gilt:<br />

1. Jede freie Variable in ϕ ist positiv beschränkt.<br />

<strong>2.</strong> Für jeden Teilausdruck (∃x)(ψ) ist die Variable x positiv beschränkt in ψ.<br />

3. Für jeden Teilausdruck (∀x)(ψ) ist die Variable x negativ beschränkt in ψ.<br />

Je<strong>der</strong> erlaubte Ausdruck ist wertebereichsunabhängig und demnach sicher. Damit läßt sich ein Algorithmus<br />

angeben, <strong>der</strong> überprüft, ob ein gegebener Ausdruck wertebereichsunabhängig ist:<br />

1. Ist <strong>der</strong> Ausdruck nach obiger Definition erlaubt? Wenn ja: <strong>der</strong> Ausdruck ist wertebereichsunabhängig.<br />

<strong>2.</strong> Sonst: Läßt sich ein Gegenbeispiel angeben? Man konstruiert sich ein Universum, daß genau die Konstanten<br />

aus dem Datenbankzustand und <strong>der</strong> Anfrage enthält und führt die Anfrage aus. Anschließend fügt man weitere<br />

Werte zum Universum hinzu und führt die Anfrage erneut aus. Wenn sich unterschiedliche Ergebnisse<br />

erzeugen lassen, ist die Anfrage wertebereichsabhängig.<br />

3. Falls kein Gegenbeispiel gefunden wurde: läßt sich die Formel umstellen (De Morgansche Gesetze, Quantorumformung,<br />

etc.)? Falls ja, gehe zu 1.<br />

4. Falls nicht: keine Entscheidung möglich.<br />

Bereichsbeschränkte TRC-Ausdrücke.<br />

Es gibt eine weitere Möglichkeit, nur sichere und wertebereichsunabhängige Ausdrücke zu formulieren: Variablen<br />

müssen strikt an Relationenschemata gebunden werden:<br />

• freie Variablen stehen in einem Term <strong>der</strong> Form R(x)<br />

• Quantifizierte Variablen werden nur mit Tupeln aus einer Relation belegt:<br />

(∃x ∈ R)(ϕ)<br />

(∀x ∈ R)(ϕ)<br />

TRC-Ausdrücke dieser Form heißen beschränkte Ausdrücke bzw. R-beschränkte Ausdrücke. Bei R-beschränkten<br />

Ausdrücken ist eine Projektion auf Attribute in <strong>der</strong> Zielliste nicht länger syntaktischer Zucker. Beispiele sind:<br />

Welche Studenten hören welche Vorlesung?“<br />

”<br />

s.MatrikelNr, h.V orlesungsNr | ST UDENT (s) ∧ HOERT (h) ∧ h.MatrikelNr = s.MatrikelNr<br />

Welche Studenten hören alle Vorlesungen?“<br />

”<br />

s.Name |<br />

ST UDENT (s) ∧ (∀v ∈ V ORLESUNG)(<br />

(∃h ∈ HOERT )(h.MatrikelNr = s.MatrikelNr ∧ h.V orlesungsNr = v.V orlesungsNr)<br />

)


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 33<br />

Integritätsbedingung: ”<br />

Je<strong>der</strong> Student hört mindestens zwei verschiedene Vorlesungen.“<br />

(∀s ∈ ST UDENT )(<br />

(∃h1 ∈ HOERT )(<br />

(∃h2 ∈ HOERT )(<br />

h1.MatrikelNr = s.MatrikelNr ∧ h<strong>2.</strong>MatrikelNr = s.MatrikelNr∧<br />

¬(h1.V orlesungsNr = h<strong>2.</strong>V orlesungsNr)<br />

)))<br />

Gib die Namen und Matrikelnummern <strong>der</strong> Studenten, die eine Vorlesung hören, die von einem Dozenten namens<br />

Meyer gehalten wird.<br />

s.Name, s.MatrikelNr |<br />

ST UDENT (s) ∧ (∃h ∈ HOERT )(h.MatrikelNr = s.MatrikelNr∧<br />

(∃d ∈ DOZENT )(d.V orlesungsNr = h.V orlesungsNr∧<br />

(∃m ∈ MIT ARBEIT ER)(<br />

m.BearbeiterNr = d.BearbeiterNr ∧ m.P ersonalNr = d.P ersonalNr∧<br />

m.Name = ′ Meyer ′<br />

)))<br />

<strong>2.</strong>3.3 Vergleich von Relationenkalkül und Relationenalgebra<br />

Proposition 2 Der algebraische Relationenkalkül und <strong>der</strong> bereichsbeschränkte Tupelkalkül und die relationale<br />

Algebra haben die gleiche Ausdruckskraft, d.h.<br />

∀db∀db ′ (∃α ∈ L Kal : eval(α(db)) = db ′ ⇔ ∃e ∈ L Al : eval(e(db)) = db ′ .<br />

Beweis durch Nachrechnen.<br />

Damit: Mengenorientierte, deklarative Semantik des Relationenkalküls kann durch Relationenalgebra korrekt und<br />

vollständig operationalisiert werden.<br />

Damit allgemeiner Zugang für die Bewertung von Datenmodellen gerechtfertigt: Die operationale Fixpunktsemantik ist gleich <strong>der</strong> deklarativen Semantik.<br />

<strong>2.</strong>3.4 Erweiterung <strong>der</strong> Relationenalgebra und des Relationenkalküls<br />

Aggregationsoperationen mit einem Zweistufenverfahren:<br />

Eine Aggregationsoperation ist definiert als Familie F = {f 0 , ...., f k , ..., f ω } mit Funktionen f k : Bag k →<br />

Num , die Multimengen mit k Elementen vom Typ T auf einen numerischen Datentyp Num abbilden. Wir<br />

lassen nur solche Typen zu, die ein minimales und ein maximales Element in dom(T ) besitzen. Es müssen<br />

zwei Eigenschaften bezüglich <strong>der</strong> Ordnung auf dom(T ) erfüllt sein:<br />

• Es gelten die Gleichungen f k (min, ...., min) = min und f k (max, ..., max) = max für die minimalen<br />

und maximalen Elemente in dom(T ).<br />

• Die Funktionen sind monoton bzgl. <strong>der</strong> Ordnung von dom(T ).<br />

Da Nullwerte explizit zugelassen sind, benutzen wir zwei Hilfsfunktionen für die strukturelle Rekursion:<br />

{<br />

h 0 0 falls s = NULL<br />

f (s) = f(s) falls s ≠ NULL<br />

h undef<br />

f (s) =<br />

{ undef falls s = NULL<br />

f(s) falls s ≠ NULL .<br />

Wir können nun die folgenden üblichen Aggregationsfunktionen einführen:<br />

Summierung in unterschiedlichen Varianten abhängig von <strong>der</strong> Behandlung von Nullwerten:


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 34<br />

• Summierung für Klassen ohne Nullwerte:<br />

sum = srec 0,Id,+ ;<br />

• Summierung für Klassen mit Nullwerten, die durch die 0 ersetzt werden:<br />

sum null<br />

0 = srec 0,h 0<br />

Id ,+ ;<br />

• Summierung für Klassen mit Nullwerten, die durch die undef ersetzt werden:<br />

sum null<br />

undef = srec 0,h undef<br />

Id ,+ .<br />

Üblich ist die Anwendung <strong>der</strong> zweiten Option.<br />

Zählen <strong>der</strong> Objekte je nach Behandlung <strong>der</strong> Nullwerte:<br />

• Für Klassen ohne Nullwerte: count = srec 0,1,+ ;<br />

• Für Klassen mit Nullwerten: count null<br />

1 = srec 0,h 0<br />

1 ,+ ;<br />

• Alternativ für Klassen mit Nullwerten: count null<br />

undef = srec 0,h undef<br />

1 ,+ .<br />

Genutzt wird oft die zweite Option.<br />

Bildung <strong>der</strong> maximalen bzw. minimalen Werte in Abhängigkeit von den Ordnungen für NULL:<br />

• Die leere Menge erlaubt keine Bestimmung von minimalen bzw. maximalen Werten:<br />

• max NULL = srec NULL,Id,max bzw. min NULL = srec NULL,Id,min<br />

• max undef = srec undef,Id,max bzw. min undef = srec undef,Id,min<br />

Diese Funktionen hängen davon ab, wie die Nullwerte in dom(T ) eingeordnet werden.<br />

Bildung des Durchschnittes: Die Durchschnittsbildung ist eine komplexere Funktion. Es gibt dafür eine<br />

Reihe von Möglichkeiten:<br />

(++)<br />

sum<br />

count<br />

(SQL!?) sumnull 0<br />

count<br />

(+?!) sumnull undef<br />

count<br />

(??)<br />

(+!)<br />

sum<br />

count null<br />

1<br />

sum null<br />

0<br />

count null<br />

1<br />

(??) sumnull undef<br />

count null<br />

1<br />

(??)<br />

(??)<br />

(++)<br />

sum<br />

count null<br />

undef<br />

sum null<br />

0<br />

count null<br />

undef<br />

sum null<br />

undef<br />

count null<br />

undef<br />

SQL benutzt eine Variante, die nicht die intuitivste ist. Wir präferieren in <strong>der</strong> HERM-Algebra die<br />

mit “+” annotierten Varianten für den Fall von Klassen mit Nullwerten. Die Funktionen avg null<br />

0 ,1 und<br />

avg null<br />

undef werden dabei <strong>der</strong> SQL-Form avgnull vorgezogen.<br />

Ordnungsoperationen je nach Basis-Datentypen und benutztem Konstruktor (Tupel, Menge)<br />

Abgeleitete Elementaroperationen sind die Modifikationsoperationen <strong>der</strong> Datenbanksysteme:<br />

Einfügen von Elementen: Die insert-Operation Insert(R C , o) ist durch die Vereinigung R C ∪{o} von<br />

Mengen für Klassen R C und Objekte o vom gleichen Typ R beschreibbar.<br />

Streichen von Elementen: Die delete-Operation Delete(R C , o) ist durch die Differenz R C \ {o} von<br />

Mengen für Klassen R C und Objekte o vom gleichen Typ R definierbar. Analog kann man auch das<br />

Streichen von Mengen delete(R C , R C′ ) einführen.<br />

Update von Elementen: Die Modifikation Update(R C , α, γ) von Klassen R C ist für Prädikate α und<br />

Ersetzungsfamilien γ = {(o, R Co )} ist definiert durch die<br />

⋃<br />

Menge<br />

R C \ σ α (R C ) ∪ R Co .<br />

o∈σ α(R C )<br />

Eine oft verwendete Definition basiert auf dem Ausdruck R C \ σ α (R C ) ∪ R C′ . Damit wird jedoch ein<br />

an<strong>der</strong>er Effekt erzielt. Gilt z.B. σ α (R C ) = ∅ und R C′ ≠ ∅, dann wird die ursprüngliche Intention verloren.<br />

Dieser Einführung liegt jedoch die oft praktizierte Ersetzung von Update(R C , o, {o ′ }) durch<br />

die Folge Delete(R C , o); InsertUpdate(R C , o ′ ) zugrunde.


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 35<br />

Eine Ersetzungsfamilie γ = {(o, R Co )} vom Typ R ist eine Menge bestehend aus einem Paar von Objekten<br />

und Klassen vom Typ R. Eine Ersetzungsfamilie beschreibt für Objekte vom Typ R jeweils eine Klasse von<br />

Objekten, durch die dieses Objekt ersetzt wird.<br />

Weitere Operationen erlauben die Einführung verschachtelter bzw. komplexer Typen (außerhalb <strong>der</strong> ersten<br />

Normalform):<br />

Schachtelung: Es sei R ′ ein Element von R. Dann wird die Schachtelung ν R ′(R C ) von R C entlang von R ′<br />

definiert als Klasse über dem Typ T = (R \ R ′ ) ⊔ R {R ′ } mit <strong>der</strong> Menge von Objekten<br />

{ o ∈ Dom(T ) | ∃o ′ ∈ R C : o[R \ R R ′ ] = o ′ [R \ R R ′ ]<br />

∧ o(R ′ ) = { o ′′ [R ′ ] | o ′′ ∈ R C ∧ o ′ [R \ R X] = t ′′ [R \ R R ′ ]}}.<br />

Entschachtelung: Es sei R ′ ein Mengenelement von R. Die Entschachtelung µ ′ R (RC ) einer Klasse definiert einen<br />

neuen Typen T = (R \ R {R ′ }) ◦ R ′ für die Konkatenation ◦ und die neue Klasse<br />

{ o ∈ Dom(T ) | ∃o ′ ∈ R C : o[R \ R {R ′ }] = o ′ [R \ R {R ′ }] ∧ o[X] ∈ o ′ (X)}.<br />

Potenzmenge: Die Potenzmenge P(R C ) = {M|M ⊆ R C } ist eine geschachtelte Klasse über dem Typ {R} .<br />

Im allgemeinen können Objekte und Strukturen mit folgenden Konstruktoren konstruiert werden:<br />

Tupelkonstruktor bzw. kartesisches Produkt<br />

Mengenkonstruktor<br />

Listenkonstruktor<br />

Vereinigungskonstruktor<br />

Multimengenkonstruktor<br />

...<br />

<strong>Relationale</strong> <strong>Datenbanken</strong> sind definiert durch Anwendungen eines Listen- auf einen Mengenkonstruktor, <strong>der</strong> wie<strong>der</strong>um<br />

auf einen Tupelkonstruktor angewandt wird.<br />

Mit den Konstruktoren sind definiert durch folgenden Definitionsrahmen:<br />

• mit Selektoren für retrieval (z.B. Select) und update-Funktionen (z.B. Insert, Delete, und Update) ür die<br />

Abbildung von Werten des neuen Typen auf die Komponententypen,<br />

• mit einem Korrektheitskriterium und Regeln zur Kontrolle <strong>der</strong> Korrektheit,<br />

• mit default-Werten<br />

• mit (ggf. mehreren Repräsentationstypen, und<br />

• mit (ggf. mehreren) Implementationstypen o<strong>der</strong> Eigenschaften <strong>der</strong> Implementationstypen.<br />

<strong>2.</strong>3.5 Beispiel zum Relationenkalkül/Tupelkalkül<br />

Angestellter(Nummer, Name, Gehalt, Abteilung, Geburtsjahr, Einstellungsdatum)<br />

Abteilung(Nummer, Name, Filiale, Stock, Leiter)<br />

Filiale(Nummer, Stadt, Land)<br />

Lieferant(Nummer, Name, Stadt, Land)<br />

Artikel(Nummer, Name, Abteilung, Preis, Bestand, Lieferant)<br />

Verkauf(Nummer, Datum, Abteilung, Artikel, Anzahl, Angestellter, Betrag)<br />

Anfragen:


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 36<br />

• Namen aller Angestellten mit einem Gehalt von weniger als 400 Euro<br />

{ t.Name | Angestellter(t) ∧ t.Gehalt < 400 }<br />

• Namen und Preise aller Artikel, die von einem Lieferanten aus Schleswig-Holstein geliefert werden<br />

{ t.Name,t.Preis | Artikel(t) ∧ ∃ l (Lieferant(l) ∧ t.Lieferant = l.Nummer ∧ l.Land = ’SH’) }<br />

• Namen und Bestände aller Filialen in Berlin<br />

{ t.Name,t.Bestand | Artikel(t) ∧ ∃ f ( Filiale(f) ∧ f.Stadt = ’Berlin’ ∧<br />

∃ v ∃ a (Verkauf(v) ∧ Abteilung(a) v.Abteilung = a.Nummer<br />

∧ a.Filiale = f.Nummer ∧ v.Artikel = a.Nummer)) }<br />

• Namen und Nummern aller Artikel, die teurer als 1.000 Euro sind und <strong>der</strong>en Bestand mindestens 500 Exemplare<br />

beträgt<br />

{ t.Name,t.Nummer | Artikel(t) ∧ t.Preis > 1.000 ∧ t.Bestand ≥ 500 }<br />

• Namen aller Abteilungen, Namen ihrer Leiter und ihre Gehälter, wobei Abteilungsleiter Angestellte sind<br />

{ t.Name,t.Abteilung, t.Gehalt | Angestellter(t) ∧ ∃ a (Abteilung(a) ∧ a.Leiter = t.Nummer) }<br />

• Alle Artikel, die in einer Abteilung verkauft wurden, <strong>der</strong>en Leiter ”Helmut K. Raffke” ist, die er aber nicht<br />

selbst verkauft hat<br />

{ t | Artikel(t) ∧ ∃ v ∃ a ∃ e1 ∃ e2 (Verkauf(v) ∧ Abteilung(a)<br />

∧ Angestellter(e1) ∧ Angestellter(e2)<br />

∧ t.Nummer = v.Artikel ∧ v.Abteilung = a.Nummer<br />

∧ a.Leiter = e.Nummer ∧ e.Name = ’Helmut K. Raffke’<br />

∧ v.Angestellter = e<strong>2.</strong>Nummer ∧ e<strong>2.</strong>Nummer ≠ e1.Nummer ) }<br />

<strong>2.</strong>4 Einführung in SQL<br />

Paradigmen<br />

formale Sprache \ Theorie Abstraktion Entwurf<br />

erfinden<br />

verwirklichen<br />

•<br />

benutzen<br />

•<br />

<strong>2.</strong>4.1 SQL<br />

SQL - tupelorientierter Relationenkalkül mit einigen algebraischen Elementen, angereichert durch arithmetische<br />

und textverarbeitende Elemente<br />

<strong>2.</strong>4.2 Vorbemerkung<br />

Erinnerung: Normalform von Ausdrücken <strong>der</strong> (einfachen) relationalen Algebra (erzeugt über Selektion, Projektion,<br />

Verbund, Differenz, Umbenennung ohne Vereinigung)<br />

• Kernausdruck: ρ γ (π X (σ α (R 1 ✶ ... ✶ R n )))<br />

• Induktiver Aufbau: anstelle von R i je<strong>der</strong> Ausdruck<br />

Vereinigung kann nachgeschoben werden, falls Typenäquivalenz nachweisbar<br />

Dreischrittverfahren aufgrund Kalkülteils<br />

1. Tupelerzeugung FROM<br />

• Semantik: Erzeugung aller Tupel t 1 ∈ R 1 , ..., t k ∈ R k


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 37<br />

• Syntax: Bindung <strong>der</strong> Tupelvariablen t 1 an das Relationensymbol R 1 , ... t k an das Relationensymbol R k<br />

<strong>2.</strong> Auswahl <strong>der</strong> gesuchten Tupel WHERE<br />

• Semantik: Auswahl aller Tupelkombinationen, die eine Formel erfüllen<br />

• Syntax: Setzen <strong>der</strong> Tupelvariablen mit entsprechend passenden Attributen und Vergleichen<br />

3. Projektion SELECT (sinnvoller Projekt)<br />

• Semantik: Auswahl <strong>der</strong> Komponenten in entsprechen<strong>der</strong> Kombination<br />

• Syntax: µ i,1 .A 1 , ..., µ i,m .A m<br />

Beispiel:<br />

PERSON = ({Name, Adresse, PNum}, {Pnum}, ∅ )<br />

STUDENT = ({PNum, SNum, Hauptf, Nebenf, Betreuer }, {SNum} , { {PNum} −→ {SNum} } )<br />

PROFESSOR = ({ PNum, Spezialis }, { PNum }, ∅ )<br />

VORLES = ({ Kurs, Raum, Zeit, Semester, Lesen<strong>der</strong>.PNum }, { Raum, Zeit, Semester }, ... )<br />

TEILNAHME = ({ Kurs, Semester, Lesen<strong>der</strong>.PNum, SNum, Note }, { SNum, Kurs, Semester }, ... )<br />

Darstellung durch Hypergraph<br />

PERSON<br />

Name<br />

Adresse<br />

PNum<br />

Spezialis<br />

PROFESSOR<br />

SNum<br />

Hauptf<br />

Nebenf<br />

Betreuer<br />

STUDENT<br />

Kurs<br />

Semester<br />

Note<br />

TEILNAHME<br />

Zeit<br />

Raum<br />

VORLES<br />

<strong>2.</strong>4.3 SQL-Schema-Definition<br />

Datendefinition in SQL<br />

<strong>DB</strong>SchemaDef := CREATE SCHEMA [ SchemaName ]<br />

[ AUTHORIZATION BenutzerName ]<br />

[ DEFAULT CHARACTER SET character-set ]<br />

[ ListeTabDef ]<br />

ListeTabDef := TabDef { TabDef }<br />

TabDef := CREATE TABLE Name ( AttrDefinitionListe


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 38<br />

TabIntegritBedingListe ) ;<br />

AttrDefinitionsListe := AttrDefinition { , AttrDefinition }<br />

AttrDefinition := AttributName Datentyp | Domain<br />

[ DefaultDefinition ]<br />

[ IntegritBedingungListe ]<br />

Datentypen: NATIONAL CHAR[ACTER] [VARYING], VARCHAR, INT[EGER], SMALLINT,<br />

NUMERIC, DEC[IMAL], FLOAT, REAL, DOUBLE PRECISION, BIT, BIT VARYING<br />

DATE, TIME, TIMESTAMP, TIME WITH TIME ZONE, TIMESTAMP WITH TIME ZONE<br />

INTERVAL<br />

IntegritBedingungListe := [ PRIMARY KEY | UNIQUE ] (AttrListe) |<br />

FOREIGN KEY (AttrListe)<br />

REFERENCES TabName [ ( AttrListe) ]<br />

[ MATCH FULL | MATCH PARTIAL ]<br />

[ ON DELETE<br />

NO ACTION | CASCADE |<br />

SET DEFAULT | SET NULL ]<br />

[ ON UPDATE<br />

NO ACTION | CASCADE |<br />

SET DEFAULT | SET NULL ]<br />

[ CHECK Klausel ]<br />

[ ASSERTION Bedingung ]<br />

Unique - Schlüssel<br />

Weiterhin noch möglich: CREATE TEMPORARY TABLE<br />

CREATE SCHEMA UniEinfach AUTHORIZATION Rektor (<br />

CREATE TABLE PERSON ( Name VARCHAR(15) NOT NULL ,<br />

Adresse VARCHAR(30),<br />

PNum INTEGER,<br />

PRIMARY KEY (PNum));<br />

CREATE TABLE STUDENT ( PNum INTEGER NOT NULL ,<br />

SNum INTEGER NOT NULL,<br />

Hauptf CHAR(3) NOT NULL,<br />

Nebenf CHAR(3),<br />

Betreuer VARCHAR(15),<br />

PRIMARY KEY (SNum)<br />

FOREIGN KEY (PNum) REFERENCES PERSON );<br />

CREATE TABLE PROFESSOR ( PNum INTEGER NOT NULL ,<br />

Spezialis CHAR(10),<br />

PRIMARY KEY (PNum)<br />

FOREIGN KEY (PNum) REFERENCES PERSON );<br />

CREATE TABLE VORLES ( Kurs VARCHAR(20) NOT NULL ,<br />

Raum CHAR(5),<br />

Zeit CHAR(3),<br />

Semester CHAR(5) NOT NULL,<br />

Lesen<strong>der</strong>.PNum INTEGER NOT NULL,<br />

PRIMARY KEY (Raum, Zeit, Semester)<br />

FOREIGN KEY (Lesen<strong>der</strong>.PNum) REFERENCES PROFESSOR );<br />

CREATE TABLE TEILNAHME ( Kurs VARCHAR(20) NOT NULL ,<br />

Semester CHAR(5) NOT NULL,<br />

Lesen<strong>der</strong>PNum INTEGER NOT NULL,


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 39<br />

DROP TABLE TEILNAHME<br />

ALTER TABLE VORLES ADD SNum INTEGER<br />

SNum INTEGER,<br />

Note DEC(2,1),<br />

PRIMARY KEY (SNum, Kurs, Semester),<br />

FOREIGN KEY (SNum) REFERENCES STUDENT ,<br />

NOT NULL<br />

ein Student muß existieren<br />

ON DELETE RESTRICT<br />

Nichtentfernen des<br />

ON UPDATE CASCADE )<br />

)<br />

letzten Student<br />

Sichtendefinition in SQL über Anfragesprache<br />

als VIRTUELLE Tabelle<br />

CREATE VIEW SUPERSTUDIOSI (Name, Fach, Lehrer)<br />

AS SELECT x.Name, y.Kurs, z.Name<br />

FROM PERSON x, TEILNAHME y, PERSON z, STUDENT, PROFESSOR<br />

WHERE STUDENT.PNum = x.PNum AND y.SNum = STUDENT.SNum<br />

AND y.Lesen<strong>der</strong>PNum = PROFESSOR.PNum AND PROFESSOR.PNum = z.PNum<br />

AND y.Note = 1.0<br />

GROUP BY x.Name<br />

DROP VIEW SUPERSTUDIOSI<br />

Vorsicht mit updates über Sichten<br />

Indizes in SQL<br />

für effiziente Verarbeitung und Suche<br />

CREATE INDEX VORLES INDEX ON VORLES (Kurs, Semester, Lesen<strong>der</strong>PNum)<br />

CREATE UNIQUE INDEX VORLES ZUGR INDEX<br />

ON VORLES (Raum, Zeit, Semester)<br />

<strong>2.</strong>4.4 SQL-Anfragen<br />

beachte Anfragen sind einfach Funktionen <strong>der</strong> Form:<br />

f : S × U → U<br />

mit Datenbank und Informationssystem-Umgebung (z.B. Anfrageinterface und Ergebnisinterface)<br />

wir unterschieden deshalb<br />

• Anfrageformen<br />

• Ergebnisformen<br />

Man hat deshalb immer einen Anfragetypen und einen Ergebnistypen.<br />

Aufgrund des Umformungssatzes gilt, daß jede Anfrage kanonisch dargestellt werden kann durch:<br />

algebraischer Ausdruck π Ri,1 .A 1 ,...,R i,m .A m<br />

(σ Φ (R 1 × ... × R k ))<br />

o<strong>der</strong> allgemeiner:


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 40<br />

map π (filter Φ (map × (R 1 , ..., R k )))<br />

entsprechen<strong>der</strong> SQL-Ausdruck<br />

SELECT DISTINCT µ 1 .A 1 ,...,µ m .A m<br />

FROM R 1 µ 1 ... R k µ k<br />

WHERE Φ<br />

Vereinfachungen<br />

• Tupelvariable kann weggelassen und R i auch verwendet werden<br />

• Klammerung µ.A kann zu A vereinfacht werden<br />

• Falls keine echte Projektion: ∗<br />

Bestimme für die Datenbankprofessoren ihre Vorlesungen.<br />

(σ Spezialis=‘<strong>Datenbanken</strong> ′(V ORLES × P ROF ESSOR))<br />

SELECT DISTINCT ∗<br />

FROM VORLES, PROFESSOR<br />

WHERE PROFESSOR.Spezialis = ‘<strong>Datenbanken</strong>’<br />

AND PROFESSOR.PNum = VORLESUNG.PNum<br />

GROUP BY PROFESSOR.PNum<br />

Bestimme alle Namen von Professoren, die <strong>Datenbanken</strong> lesen.<br />

π P ERSON.Name (σ V ORLES.Kurs=‘<strong>Datenbanken</strong> ′<br />

(P ERSON P Num ✶ P Num P ROF ESSOR P Num ✶ P Num V ORLES))<br />

SELECT DISTINCT Name<br />

FROM PERSON, PROFESSOR, VORLES<br />

WHERE PERSON.PNum = PROFESSOR.PNum<br />

AND PERSON.PNum = VORLES.PNum<br />

AND VORLES.Kurs = ‘<strong>Datenbanken</strong>’<br />

Bestimme alle Namen von Professoren, die selbst eine Vorlesung <strong>Datenbanken</strong> hörten und eine solche Vorlesung<br />

lesen.<br />

π P ERSON.Name (σ V ORLES.Kurs=‘<strong>Datenbanken</strong> ′<br />

((V ORLES Lesen<strong>der</strong>.P Num ✶ P Num P ROF ESSOR P Num ✶ P Num P ERSON<br />

P Num ✶ P Num ST UDENT ) SNum,Kurs ✶ SNum,Kurs ))<br />

σ V ORLES.Kurs=‘<strong>Datenbanken</strong> ′(T EILNAHME)))<br />

SELECT DISTINCT t.Name<br />

FROM PERSON y, PROFESSOR p , VORLES v, TEILNAHME t, STUDENT s<br />

WHERE y.PNum = p.PNum<br />

AND y.PNum = v.PNum<br />

AND v.Kurs = ‘<strong>Datenbanken</strong>’<br />

AND t.SNum = s.SNum<br />

AND s.PNum = y.PNum<br />

AND t.Kurs = ‘<strong>Datenbanken</strong>’<br />

Wird zusätzlich die Semantik benutzt (nur Studenten nehmen an Vorlesungen teil, nur Professoren lesen Vorlesungen),<br />

dann kann man die Anfrage vereinfachen:<br />

π P ERSON.Name (σ V ORLES.Kurs=‘<strong>Datenbanken</strong> ′<br />

((V ORLES Lesen<strong>der</strong>.P Num ✶ P Num P ERSON P Num ✶ P Num ST UDENT )<br />

SNum,Kurs ✶ SNum,Kurs T EILNAHME))<br />

SELECT DISTINCT t.Name<br />

FROM PERSON y, VORLES v, TEILNAHME t, STUDENT s


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 41<br />

WHERE y.PNum = v.PNum<br />

AND v.Kurs = ‘<strong>Datenbanken</strong>’<br />

AND t.SNum = s.SNum<br />

AND s.PNum = y.PNum<br />

AND t.Kurs = ‘<strong>Datenbanken</strong>’<br />

SQL erlaubt außerdem auch Multimengen. Solche sind nicht im tupelorientierten Relationenkalkül darstellbar.<br />

Generiere eine Namensliste <strong>der</strong> Vorlesungsteilnehmer für die Vorlesung(en) ‘<strong>Datenbanken</strong>’ im Wintersemester<br />

2004.<br />

Unter Voraussetzen obiger Inklusionsbedingungen erhalten wir:<br />

SELECT PERSON.Name<br />

FROM PERSON, TEILNEHMER, STUDENT<br />

WHERE PERSON.PNum = STUDENT.PNum<br />

AND STUDENT.SNum = TEILNEHMER.SNum<br />

AND TEILNEHMER.Semester = ‘WS 2004/2005’<br />

AND TEILNEHMER.Kurs = ‘<strong>Datenbanken</strong>’<br />

Wie kann man alle Teilnehmer von <strong>der</strong> Vorlesung ‘<strong>Datenbanken</strong>’ erhalten ?<br />

Man generiere zuerst eine vereinigte Teilnehmerliste aller Datenbankvorlesungen und bestimme dann eine Teilnehmertabelle.<br />

SELECT PERSON.Name<br />

FROM PERSON , STUDENT<br />

WHERE PERSON.PNum = STUDENT.PNum<br />

AND SNum IN ( SELECT DISTINCT SNum<br />

FROM STUDENT, TEILNEHMER<br />

WHERE STUDENT.SNum = TEILNEHMER.SNum<br />

AND TEILNEHMER.Semester = ‘WS 2004/2005’<br />

AND TEILNEHMER.Kurs = ‘<strong>Datenbanken</strong>’ )<br />

Komplexere Anfragen bedürfen einer wohldurchdachten Umsetzung !<br />

Man generiere die Namen aller Studenten, die alle Vorlesungen gehört haben, die Professor ‘Gerste’ gelesen hat.<br />

SELECT DICTINCT x.Name<br />

FROM PERSON x, STUDENT s<br />

WHERE x.PNum = S.PNum<br />

AND NOT EXISTS (SELECT *<br />

FROM PERSON y, VORLES z<br />

WHERE y.Name = ‘Gerste’ AND y.PNum = z.Lesen<strong>der</strong><br />

AND NOT EXISTS (SELECT *<br />

FROM TEILNAHME t<br />

WHERE y.PNum = t.Lesen<strong>der</strong><br />

AND t.Kurs = z.Kurs<br />

AND s.SNum = t.SNum ) )<br />

All Mitarbeiter, die einen Kurs leiten, an <strong>der</strong> <strong>der</strong> Leiter ihres Institutes teilnimmt.<br />

SELECT m<strong>2.</strong>PersNr, m<strong>2.</strong>Name<br />

FROM Mitarbeiter m1, Mitarbeiter m2, Institut, Kurs, Kursteilnahme<br />

WHERE m<strong>2.</strong> Institut = Insitut.Bezeichnung AND Institut.PersNrLeiter = m1. PersNr AND<br />

Kursteilnahme.KursNr = Kurs.KursNr AND Kurs.Leitung = m<strong>2.</strong>PersNr;<br />

an<strong>der</strong>e Version davon als geschachtelte Variante<br />

SELECT m<strong>2.</strong>PersNr, m<strong>2.</strong>Name


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 42<br />

FROM Mitarbeiter m2<br />

WHERE m<strong>2.</strong>Institut IN<br />

(SELECT Bezeichnung<br />

FROM Institut i<br />

WHERE i.PersNrLeiter IN<br />

(SELECT PersNr<br />

FROM Kursteilnahme<br />

WHERE KursNr IN<br />

(SELECT KursNr<br />

FROM Kurs<br />

WHERE Leitung = m<strong>2.</strong>PersNr)));<br />

an<strong>der</strong>e Varianten durch Auswertung von 2 Wegen über m1 zu Mitarbeiter m2<br />

Backus-Naur-Form einfacher SQL-Anfragen: { - beliebig oft (0..),<br />

[ - optional, | - choice, @ - rechtsassoziativer Operator<br />

einfache SQL-Anfrage := SELECT DISTINCT Attributtermliste<br />

FROM Variablenbindungsliste<br />

[ WHERE Formel ]<br />

[ GROUP BY Gruppierung ]<br />

[ HAVING Suchbedingung ]<br />

[ ORDER BY Gruppierung ]<br />

Attributtermliste := ∗ | AttributTerm [ { , AttributTerm } ]<br />

Attributterm := [ Tupelvariable . | Relationensymbol . ] Attribut<br />

Variablenbindungsliste := Relationensymbol [ Tupelvariable ]<br />

[ { , Variablenbindungsliste } ]<br />

FORMEL := Atomformel | NOT Formel | ( Formel )<br />

Formel AND Formel |<br />

Formel OR Formel<br />

Atomformel := Term Vergleichsprädikat Term<br />

Term := Attributterm | Konstantenzeichen<br />

Vergleichsprädikat := = | ̸=<br />

Gruppierung := Attributterm { , Attributterm }<br />

Suchbedingung<br />

Algebraischer Teil<br />

SQL-Anfrage := einfache SQL-Anfrage | Mengenop SQL-Anfrage<br />

Mengenop := INTERSECT | UNION | MINUS<br />

Multimengen-Teil<br />

ohne DISTINCT<br />

Genestete Anfragen<br />

im WHERE-Teil an<strong>der</strong>e Anfrage<br />

gekoppelt über IN (Tupel Element <strong>der</strong> inneren Anfrage)<br />

EXISTS (eine Menge ist nicht leer)<br />

NOT EXISTS (eine Menge ist leer)<br />

gekoppelt über Variable<br />

Namen, Adresse aller Studenten ohne Fehlleistung<br />

SELECT Name, Adresse<br />

FROM PERSON , STUDENT<br />

WHERE PERSON.PNum = STUDENT.SNum


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 43<br />

AND NOT EXISTS ( SELECT ∗<br />

FROM TEILNAHME<br />

WHERE TEILNAHME.SNum = STUDENT.SNum<br />

AND TEILNAHME.Note = 5<br />

ORDER BY Name )<br />

Dazu ist die folgende Anfrage äquivalent:<br />

SELECT Name, Adresse<br />

FROM PERSON<br />

WHERE PNum IN (SELECT PNum<br />

FROM STUDENT<br />

WHERE NOT EXISTS ( SELECT ∗<br />

FROM TEILNAHME<br />

WHERE TEILNAHME.SNum = STUDENT.SNum<br />

AND TEILNAHME.Note = 5 ) )<br />

Explizite Werteangabe<br />

Wie oft ist ein Student in ‘<strong>Datenbanken</strong>’ (fast) durchgefallen?<br />

SELECT COUNT(∗)<br />

FROM TEILNAHME<br />

WHERE TEILNAHME.Note IN (4,5) AND TEILNAHME.Kurs = ‘<strong>Datenbanken</strong>’<br />

Geschachtelte Anfragen sind auch möglich in SELECT- und FROM-Teilen<br />

• geschachtelte Anfragen im SELECT-Teil<br />

Lehrbelastung aller Profs<br />

SELECT PersNr, Name, (SELECT sum(SWS) AS Lehrbelastung<br />

FROM Vorlesungen<br />

WHERE Dozent = PersNr)<br />

FROM Person<br />

• Anfrage kann auch mit FROM-Teil verbunden sein: (Marktanteil <strong>der</strong> Dozenten)<br />

SELECT t.KursNr, t.AnzahlProVorlesung, g.GesamtAnzahl<br />

h.AnzahlProVorlesung/g.GesamtAnzahl AS Marktanteil<br />

FROM (SELECT KursNr, COUNT(*) AS AnzahlProVorlesung<br />

FROM Teilnehmer<br />

GROUP BY KursNr) t,<br />

(SELECT COUNT(*) AS GesamtAnzahl<br />

FROM Student ) g;<br />

Geschachtelte Anfragen können mitunter einfach aufgelöst werden:<br />

• SELECT *<br />

FROM Student s<br />

WHERE EXISTS<br />

(SELECT p.*<br />

FROM Professor p<br />

WHERE p.Geburtsdatum > s.Geburtsdatum );<br />

• SELECT *<br />

FROM Student s JOIN Person p1 ON p1.Name = s.Name AND p1.Geburtsdatum = s.Geburtsdatum<br />

WHERE s.Geburtsdatum <<br />

(SELECT max(p.Geburtsdatum)


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 44<br />

FROM Professor p);<br />

Geschachtelte Anfragen können durch Umformungen aufgelöst werden:<br />

• SELECT m.*<br />

FROM Mitarbeiter m JOIN LeiterVon l ON m.PersNr = l.MitarbeiterPersNr<br />

WHERE EXISTS<br />

(SELECT p.*<br />

FROM Professor p<br />

WHERE l.Chef = m.PersNr AND p.Geburtsdatum < s.Geburtsdatum);<br />

• SELECT *<br />

FROM Mitarbeiter m JOIN LeiterVon l ON m.PersNr = l.MitarbeiterPersNr<br />

JOIN Professor p ON p.PersNr = l.Chef ;<br />

Aufgrund des Fehlens von ∀ und ⇒ in SQL muß eine Umformung vorgenommen werden, falls man <strong>der</strong>artige<br />

Aussagen braucht:<br />

alle Studenten, die alle vierstündigen Vorlesungen hören<br />

SELECT s.*<br />

FROM Student s<br />

WHERE s.Hautfach = “Informatik” AND<br />

NOT EXISTS<br />

(SELECT *<br />

FROM Vorlesung v<br />

WHERE v.SWS = 4 AND NOT EXISTS<br />

(SELECT *<br />

FROM Teilnahme t<br />

WHERE t.KursNr = v.KursNr AND t.MatrNr = s.MatrNr));<br />

Kommerzielle Systeme können dies mitunter schwer auflösen<br />

COUNT-Trick<br />

alle Studenten, die alle Vorlesungen hören<br />

SELECT s.*<br />

FROM Student s JOIN Teilnahme t ON s.MatrNr = t.MatrNr<br />

WHERE s.Hautfach = “Informatik”<br />

GROUP BY s.MatrNr SELECT s.*<br />

HAVING COUNT(*) =<br />

(SELECT COUNT(*) FROM Vorlesung JOIN Professor ON Vorlesung.Dozent = Professor.PersNr<br />

WHERE Professor.In = “Institut für Informatik”);<br />

Arithmetischer Teil<br />

Aggregatfunktionen: AVG, SUM, MAX, MIN, COUNT<br />

4 Grundrechenarten<br />

arithmetische Vergleichsoperationen<br />

Wie oft ist ein Student in ‘<strong>Datenbanken</strong>’ durchgefallen?<br />

SELECT COUNT(∗)<br />

FROM TEILNAHME<br />

WHERE TEILNAHME.Note = 5 AND TEILNAHME.Kurs = ‘<strong>Datenbanken</strong>’


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 45<br />

Was ist die Durchschnittnote in ‘<strong>Datenbanken</strong>’ ? Wieviele Teilnehmer hatte dieser Kurs insgesamt ?<br />

SELECT AVG(Note), COUNT(∗)<br />

FROM TEILNAHME<br />

WHERE TEILNAHME.Note = 5 AND TEILNAHME.Kurs = ‘<strong>Datenbanken</strong>’<br />

Textverarbeiten<strong>der</strong> Teil<br />

Konstantenzeichen sind nichtatomare Zeichenfolgen, die man bzgl. Vorkommen von Teilworten testen, konkatenieren<br />

usw. kann<br />

LIKE<br />

Update-Operationen<br />

INSERT INTO PERSON VALUES (‘Gerste’, ‘Zentrum’, 0815)<br />

auch mit Tabellen<br />

INSERT INTO TEILNAHME SELECT x.Kurs, x.Semester, x.PNum,, y.SNum, z.Note<br />

FROM VORLESUNG x, STUDENT y, TEILNAHME t,<br />

PERSON, TEILNAHME z<br />

WHERE x.Kurs LIKE ‘%Geschichte%’ AND PERSON.PNum = y.PNum<br />

AND PERSON.Name LIKE ‘B% AND z.SNum = y.SNum<br />

AND NOT EXISTS (SELECT *<br />

FROM TEILNAHME w<br />

WHERE w.SNum = z.SNum AND w.Note < z.Note<br />

(alle Studenten mit B*-Namen haben die ‘Geschichte’-Kurse zu besuchen, erhalten dann gleich ihre beste Note)<br />

(manchmal statt Buchstaben)<br />

DELETE FROM PROFESSOR WHERE Spezialis LIKE ‘%Geschichte%’<br />

UPDATE VORLES<br />

SET Raum = ‘HG133’<br />

WHERE Raum = ‘HG 130’ AND Zeit = ‘Mo2’ AND Semester = ‘WS94’<br />

<strong>2.</strong>4.5 Erweiterungen<br />

Embedded SQL<br />

eingebettet in eine Hostsprache<br />

Zugriffsrechte<br />

siehe Abschnitt 4.1. <strong>der</strong> Vorlesung<br />

definiert über GRANT<br />

Direktdefinition <strong>der</strong> Operationen<br />

in SQL2<br />

Projektion<br />

SELECT DISTINCT ... FROM R<br />

Selektion<br />

SELECT * FROM R WHERE Φ


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 46<br />

Vereinigung<br />

SELECT DISTINCT ... ... UNION SELECT DISTINCT ...<br />

Differenz<br />

SELECT DISTINCT * FROM R EXCEPT SELECT DISTINCT * FROM S<br />

Verbund<br />

SELECT * FROM R NATURAL JOIN S<br />

Kartesisches Produkt<br />

SELECT * FROM R CROSS JOIN S<br />

Theta-Verbund<br />

SELECT * FROM R JOIN S ON R.B = S.C<br />

Outer Join (äußerer Verbund)<br />

SELECT * FROM R LEFT OUTER JOIN S ON ..<br />

hängende Tupel von R um Nullwerte ergänzt über S<br />

analog RIGHT OUTER JOIN<br />

und FULL OUTER JOIN<br />

Nullwerte-Auswertung in SQL<br />

• in arithmetischen Ausdrücken propagiert (NULL führt zu NULL)<br />

• SQL nutzt einfache dreiwertige Logik mit UNKNOWN als Rückgabewert bei NULL<br />

• logische Operatoren AND, NOT, OR als mittleren Wert<br />

• in WHERE-Bedingung nur solche Tupel weitergereicht, die zu ‘true’ ausgwertet werden<br />

• beim Gruppieren ist NULL eine eigene Gruppe<br />

es wird aufgrund <strong>der</strong> SQL-Auswertung: nur zu ‘true’-ausgewertete Bedingungen werden weiter ausgewertet<br />

dann ggf. nur zu “Mit Sicherheit bekannt, daß ... ” ausgewertet<br />

Beispiel:<br />

• äquivalente Anfragen:<br />

• SELECT P.Name<br />

FROM Person P<br />

WHERE NOT EXISTS<br />

(SELECT *<br />

FROM FamousPeople F<br />

WHERE F.Geburtsdatum = P. Geburtsdatum);<br />

• SELECT P.Name<br />

FROM Person P<br />

WHERE P.Geburtsdatum NOT IN<br />

(SELECT Geburtsdatum<br />

FROM FamousPeople F);<br />

• nicht äquivalent sind dagegen für z.B. den Fall, daß alle Geburtstage <strong>der</strong> in Kiel geborenen in FamousPeople<br />

fehlen:


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 47<br />

• SELECT P.Name<br />

FROM Person P<br />

WHERE NOT EXISTS<br />

(SELECT *<br />

FROM FamousPeople F<br />

WHERE F.Geburtsdatum = P. Geburtsdatum AND<br />

F. Geburtsort = “Kiel”);<br />

wird ausgewertet zu allen Tupeln in Person<br />

weil F.Geburtsdatum = NULL<br />

demzufolge nicht true son<strong>der</strong>n unknown<br />

deshalb is NOT EXISTS (∅) stets wahr<br />

• SELECT P.Name<br />

FROM Person P<br />

WHERE P.Geburtsdatum NOT IN<br />

(SELECT Geburtsdatum<br />

FROM FamousPeople F<br />

WHERE F. Geburtsort = “Kiel”);<br />

nur unbekannte Geburtstage, demzufolge keine Antworttupel<br />

Darstellung <strong>der</strong> Rekursion in SQL<br />

ORACLE-Variante<br />

SELECT KursTitel<br />

FROM Kurs<br />

WHERE KursNr IN (SELECT Vorgänger<br />

FROM Voraussetzung<br />

CONNECT BY Nachfolger = PRIOR Vorgänger<br />

START WITH Nachfolger = (SELECT KursNr<br />

FROM Kurs<br />

WHERE KursTitel = ‘Datenbanksysteme I’));<br />

<strong>DB</strong>2-Variante<br />

WITH TransHülle (Vorg, Nachf)<br />

AS (SELECT Vorgänger, Nachfolger FROM Voraussetzung<br />

UNION ALL<br />

SELECT t.Vorg, v.Nachfolger<br />

FROM TransHülle t, Voraussetzung v<br />

WHERE t.Nachf = v.Vorgänger)<br />

SELECT KursTitel<br />

FROM Kurs<br />

WHERE KursNr IN<br />

(SELECT Vorg FROM TransHülle WHERE Nachf IN<br />

(SELECT KursNr<br />

FROM Kurs<br />

WHERE KursTitel = ‘Datenbanksysteme I’));<br />

SQL-Entwicklung im Überblick als Diagramm 2:


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 48<br />

Rekursion<br />

Komplexe Datentypen, SQL/PSM, SQL/CLI, SQL/MED,<br />

SQL/OLB, SQL/Schemata, SQL/JRT, SQL/XML<br />

Strukturelle Objektoptimierung<br />

Abstrakte Datentypen<br />

SQL-Funktionen, prozedurale Elemente<br />

Neue Funktionen: RECURSIVE JOIN,<br />

JOIN USING FOREIGN KEY<br />

Trigger, Sicherungspunkte<br />

Call-level-Interface<br />

Schnittstellendefinition für dynamisches<br />

SQL über C-Funktionsaufrufe<br />

CREATE ASSERTION<br />

SET CONSTRAINT<br />

Rollen<strong>der</strong> Cursor<br />

FETCH PRIOR, FETCH RELATIVE<br />

Verbindungsaufbau<br />

zwischen Client/Server<br />

OUTER JOIN, UNION JOIN<br />

UNION EXCEPT, INTERSECT<br />

Domains, Schemamanipulat. (ALTER)<br />

Referentielle Aktionen<br />

Dynamisches SQL<br />

Erweit. d. Hostsprachen<br />

(ADA, C)<br />

Erweit. Fehlermeld.<br />

SQL-Einbett. in<br />

Hostsprachen<br />

(COBOL, PL/1)<br />

Erweit. Int.-beding.<br />

PRIMARY KEY, FOREIGN KEY, CHECK<br />

Datendefintion<br />

Datenmanipulation<br />

ANSI<br />

SQL/89<br />

Level 2<br />

Embedded<br />

SQL<br />

X/Open<br />

SAG<br />

CLI<br />

SQL/92<br />

Full<br />

level<br />

SQL/92<br />

Intermediate<br />

level<br />

SQL/92<br />

Entry<br />

Level<br />

SQL 4<br />

als<br />

SQL:2003<br />

SQL 3<br />

als<br />

SQL:1999<br />

ANSI<br />

ANSI<br />

SQL<br />

SQL/89<br />

Level 1<br />

1986 1989 1989 1991 1992 1995/99 2000/03<br />

Abbildung 2: Die Entwicklung von SQL und Funktionalität


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 49<br />

<strong>2.</strong>4.6 QBE<br />

entwickelt von IBM Yorktown Heights für Büroautomation<br />

werteorientierter Relationenkalkül ohne viel Logikvoraussetzungen<br />

Konzepte<br />

Tabellengerüst jede Relation durch Tabelle darstellbar<br />

Beispiele Werte für σ<br />

Variable alle nicht durch “P” gebundenen Variablen sind mit <strong>der</strong> Semantik ∃ definiert<br />

Operatoren P (rint), I (nsert), D (elete), U (pdate)<br />

Verbindung über Variable<br />

Zeilen einer Tabelle als ∨ interpretiert; evt. auch mit ¬<br />

Ergebnis: alle Tupel, die auf Bedingungen passen<br />

Vergleichsoperatoren über Variable<br />

Generiere eine Namensliste <strong>der</strong> Vorlesungsteilnehmer für die Vorlesung(en) ‘<strong>Datenbanken</strong>’ im Wintersemester<br />

2004.<br />

PERSON Name Adresse PNum<br />

P.x<br />

y<br />

TEILNEHMER Kurs Semester Lesen<strong>der</strong>.PNum SNum Note<br />

‘<strong>Datenbanken</strong>’ ‘WS 2004/2005’ z<br />

STUDENT PNum SNum Hauptf Nebenf Betreuer<br />

y z<br />

Namen, Adresse aller Studenten mit mindestens einmal ohne Fehlleistung<br />

PERSON Name Adresse PNum<br />

P. P. y<br />

TEILNEHMER Kurs Semester Lesen<strong>der</strong>.PNum SNum Note<br />

¬ z 5<br />

STUDENT PNum SNum Hauptf Nebenf Betreuer<br />

y z<br />

weiterhin: Datenschemadefinition über leere Tabelle<br />

analog Sichtendefinition<br />

<strong>2.</strong>4.7 Visual SQL<br />

Datenbank-Programmierung ist für den Novizen und auch den Programmierer oft ein Buch mit sieben Siegeln,<br />

sobald die Programmieraufgabe etwas komplexer wird. Der Grund liegt auf <strong>der</strong> Hand: Es ist unmenschlich, eine<br />

o<strong>der</strong> auch mehrere Seiten Code zu lesen, diesen zu verstehen und auch in allen Facetten zu erfassen. Meist sind<br />

viele kleinere Nebenbedingungen mit zu erfassen bzw. im Auge zu behalten. Oft erschweren Unzulänglichkeiten<br />

von SQL auch die Formulierung.<br />

In diesem Teil des Skriptum wird eine an<strong>der</strong>e Auffassung begründet, die sich mehr auf die Möglichkeiten <strong>der</strong><br />

multimedialen Welt stützt und dem Benutzer durch eine graphische Gestaltung entgegen kommt. Es wird basierend<br />

auf dem ER-Modell ein an<strong>der</strong>e Formulierung von komplexen SQL-Anfragen vorgenommen, die sich stark an das<br />

ER-Paradigma anlehnt.


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 50<br />

SQL - Möglichkeiten und Grenzen.<br />

SQL ist wie jede lineare Sprache beschränkt überschaubar. Schemata sind wesentlich besser geeignet, um<br />

strukturelle Zusammenhänge einfach und zugleich konsistent zu beherrschen. Deshalb wird eine Sprache Visual<br />

SQL entwickelt, mit <strong>der</strong> die Datenbankprogrammierung visualisiert werden kann.<br />

SQL ist als Kompromiss entstanden. SQL hat als Sprache <strong>der</strong> vierten Generation viel aus den Fehlern an<strong>der</strong>er<br />

Programmiersprachen gelernt. Durch eine auf Kompromiss ausgerichtete Standardisierung sind allerdings auch<br />

‘features’ entstanden, die wenig durchdacht erscheinen und <strong>der</strong>en Anwendung auch eine gute Ausbildung und viel<br />

Praxiserfahrung erfor<strong>der</strong>t. Die Vor- und Nachteile von relationalen Sprachen sind sehr gut in Heuer92 erläutert.<br />

Die Einschränkung auf relational vollständige Sprachen ist an <strong>der</strong> Einfachheit und relativen problemlosen Realisierbarkeit<br />

<strong>der</strong> relationalen Algebra orientiert. Zum an<strong>der</strong>en ist SQL eine Sprache, die weit über die Mächtigkeit<br />

<strong>der</strong> Prädikatenlogik <strong>der</strong> ersten Stufe hinausgeht. Damit ist bereits <strong>der</strong> gut ausgebildete Informatiker relativ einfach<br />

zu überfor<strong>der</strong>n. Grund für diese ungerechtfertigte Mächtigkeit sind Aggregations- und Gruppierungsoperationen,<br />

denen eine wohldurchdachte Ausarbeitung nicht zugesprochen werden kann. Noch schlimmer sind Nullwerte, die<br />

mit amerikanischer Unbedarftheit eingeführt worden sind, die in <strong>der</strong> praktischen Benutzung stark mit unterschiedlichen<br />

Bedeutungen belastet werden und aufgrund <strong>der</strong> fehlenden Dokumentationserzwingung von SQL auch dann<br />

einen Benutzer zum Kunden des Orakels von Delphi werden lässt. Typisch für den letzteren Fall sind Unterscheidungen,<br />

die ein Benutzer zwischen NOT IN und NOT EXISTS vornehmen muss, sobald Nullwerte erlaubt<br />

sind.<br />

SQL ist bewusst so beschränkt worden, damit alle Algorithmen, die die Datenbankoperationen unterlegen, auch<br />

mit einer maximalen Komplexität von O(n log n) realisiert werden können. Dazu gehört auch die Nichtaufnahme<br />

einer Rekursion in SQL’9<strong>2.</strong><br />

Wie je<strong>der</strong> Visualisierung ist auch Visual SQL eine Grenze gesetzt. Visualisierung ist nur dann sinnvoll, wenn<br />

sie überschaubar bleibt, d.h. auf ein Teilschema begrenzt, das sich auf einer Seite repräsentieren lässt. Visualisierung<br />

ist nutzlos für sehr grosse Zusammenhänge, ersetzt auch nicht das Nachdenken und Formulieren, son<strong>der</strong>n<br />

dient nur als Hilfestellung. Die undurchdachte Losung, dass durch ein Bild tausend Worte ersetzt werden, ist von<br />

Denkfaulen leicht akzeptiert, hält aber keiner genaueren Betrachtung stand. SQL und Programmierung erfor<strong>der</strong>n<br />

eine Ausbildung und können we<strong>der</strong> in Jauch’schen Quiz-Shows noch in bebil<strong>der</strong>ten Knoff-Hoff-Sendungen gelernt<br />

werden.<br />

Jede Gemeinschaft lebt von <strong>der</strong> Entwicklung, so auch die SQL-Programmierer- und -Anwen<strong>der</strong>-Gemeinschaft.<br />

SQL wurde bereits in <strong>der</strong> Variante von SQL’92 mit Konstrukten versehen, die einer theoretischen Basis entbehren.<br />

So wird z.B. die Erzwingung von Integritätsbedingungen mit einer Vielzahl von Varianten unterstützt, die nicht<br />

ohne weiteres unterschieden werden und modelliert werden können. Es können Integritätsbedingungen vor <strong>der</strong><br />

Ausführung von Anweisungen kontrolliert werden und so auch die Ausführung vollständig blockieren, solange<br />

die Datenbank sich in einem Zustand befindet, <strong>der</strong> inkonsistent zu den Bedingungen ist. Damit wird eine globale<br />

Semantik des Datenbankverhaltens unterstützt. Dies war sicherlich nicht die Intention von SQL’9<strong>2.</strong> Die Isolationsmodi<br />

für Transaktionen sind ein an<strong>der</strong>es Beispiel. Da ein Programm auch die Kontrolle <strong>der</strong> Integritätsbedingungen<br />

mit steuern kann, werden auch dynamische Integritätsbedingungen unterstützt.<br />

Ein Problemkreis von SQL muss mit beson<strong>der</strong>er Vorsicht behandelt werden: SQL nutzt Multimengen (“bag”)<br />

und nicht nur Mengen. Demzufolge haben die relationalen Operationen an<strong>der</strong>e Gesetzmässigkeiten als die SQL-<br />

Operationen. Damit werden auch Auswertungsoperationen an<strong>der</strong>s spezifizierbar, kommutieren nicht und müssen<br />

auf an<strong>der</strong>e Art programmiert werden.<br />

Ausführliche Darstellung von Visual SQL und Sourcen.<br />

siehe in den Materialien zur Vorlesung und vor allem zu den Übungen<br />

Literaturhinweis<br />

Bernhard Thalheim: Entity-Relationship Modeling, Foundations of Database Technology. Springer, 2000. ISBN<br />

3-540-65470-4


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 51<br />

An die Teilnehmer <strong>der</strong> Veranstaltung wird <strong>der</strong> Verkauf des Buches zu einem ermäßigten Preis (80% bzw. weniger) durch das<br />

Sekretariat TIS organisiert. Bitte sprechen Sie persönlich bei Frau Kruse vor.<br />

Joachim Biskup: Grundlagen von Informationssystemen, Vieweg, 1995<br />

Das Skriptum zu Vorlesungen zu diesem Buch ist abgelegt unter:<br />

http://www.is.informatik.uni-kiel.de/∼thalheim/vorlesungen/biskup/Biskup.pdf<br />

Alfons Kemper, André Eickler: Datenbanksysteme - Eine Einführung, 5. Auflage. Oldenbourg 2003<br />

Die Skripte zur Vorlesung sind abgelegt unter:<br />

http://www.is.informatik.uni-kiel.de/∼thalheim/vorlesungen/kemper/kapitel1.pdf — kapitel 13.pdf<br />

Weitere Literaturquellen sind:<br />

• Ramesh Elmasri, Sham B. Navathe: Fundamentals of Database Systems (4nd Edition), Benjamin/Cummings,<br />

Redwood City etc., 2004 (auch in Deutsch)<br />

• Jeffrey D. Ullman, Jennifer Widom: A First Course in Database Systems. Prentice-Hall 2007<br />

• Andreas Heuer, Gunter Saake: <strong>Datenbanken</strong>: Konzepte und Sprachen. Pearson 2000<br />

• Chris Date: An Introduction to Database Systems, 8th ed., Pearson, 2004.<br />

• A. Silberschatz, H. F. Korth, S. Sudarshan: Database System Concepts, McGraw-Hill, 2001.


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 52<br />

Anhang<br />

8<br />

Logik in a nutshell<br />

Um eine unmißverständliche Anfrage an ein Datenbanksystem zu stellen, ist eine formale Definition <strong>der</strong> Anfragesprache<br />

notwendig. Diese Definition bestimmt, welche Anfragen als gültig betrachtet werden und welche Bedeutung<br />

(Semantik) diesen Anfragen zugeordnet ist.<br />

Wir behandeln hier zwei Ansätze formaler Sprachen für die Formulierung von Anfragen an Datenbanksysteme.<br />

Die relationale Algebra definiert eine Menge von möglichen Operationen über den Relationen einer Datenbank.<br />

Diese Operationen bilden die Relationen <strong>der</strong> Datenbank auf an<strong>der</strong>e Relationen ab. Eine Anfrage <strong>der</strong> relationalen<br />

Algebra ist eine Folge von Anweisungen, die angibt, welche Operationen auf welche Relationen angewendet<br />

werden müssen, um das gewünschte Ergebnis zu erhalten.<br />

Der relationale Tupelkalkül geht einen an<strong>der</strong>en Weg: mit Hilfe einer Sprache werden die Eigenschaften des<br />

gewünschten Ergebnisses beschrieben. Das Datenbanksystem bestimmt aus den Relationen <strong>der</strong> Datenbank den<br />

Zustand, <strong>der</strong> diese Eigenschaften erfüllt.<br />

Beide Anfragesprachen benutzen die mathematischen Grundlagen <strong>der</strong> Logik. Deshalb beginnen wir in diesem<br />

Skript mit einer kurzen Einführung in die Begriffswelt <strong>der</strong> Logik. Dabei beschränken wir uns auf die Elemente, die<br />

für unsere Anfrageformulierung wichtig sind.<br />

Aussagenlogik<br />

Formeln, Interpretationen und Modelle<br />

Die Aussagenlogik stellt einen Rahmen für die Bestimmung <strong>der</strong> Wahrheitgehalts von Aussagen bzgl. einer gegebenen<br />

Welt bereit. Eine Aussage wird dabei aus Teilaussagen zusammengesetzt, die mittels Junktoren verbunden<br />

werden. Die Basis bilden strukturlose Elementaraussagen, die nicht weiter zerlegt werden können.<br />

Betrachten wir folgende Aussagen:<br />

A 1 : ”<br />

Es regnet.“<br />

A 2 : ”<br />

Die Straße ist naß.“<br />

Aus beiden (Elementar-)Außagen können weitere Aussagen zusammengesetzt werden:<br />

A 3 : ”<br />

Es regnet und die Straße ist naß.“<br />

A 4 : ”<br />

Wenn es regnet, ist die Straße naß.“<br />

A 5 : ”<br />

Die Straße ist nicht naß.“<br />

A 6 : ”<br />

Wenn die Straße naß ist, regnet es.“<br />

A 7 : ”<br />

Wenn es regnet, ist die Straße naß. Die Straße ist nicht naß. Es regnet nicht.“<br />

A 8 : ”<br />

Die Straße ist genau dann naß, wenn es regnet.“<br />

Das Verbinden von Teilaussagen zu komplexeren Aussagen geschieht mit Hilfe von Junktoren. Typische Junktoren<br />

sind ”<br />

und“ (∧), ”<br />

o<strong>der</strong>“ (∨), ”<br />

nicht“ (¬), die Implikation (⇒) und die Äquivalenz (⇔). Mit Hilfe dieser<br />

Symbole lassen sich die Aussagen A 3 bis A 8 z.B. wie folgt als Formeln schreiben:<br />

A 3 : A 1 ∧ A 2<br />

8 Dieser Anhang wurde von G. Fiedler erstellt.


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 53<br />

A 4 : A 1 ⇒ A 2<br />

A 5 : ¬A 2<br />

A 6 : A 2 ⇒ A 1<br />

A 7 : (A 1 ⇒ A 2 ) ∧ (¬A 2 ) ∧ (¬A 1 )<br />

A 8 : A 1 ⇔ A 2<br />

Bis jetzt ist eine Aussage nur ein syntaktischer Ausdruck, dem eine Bedeutung (Semantik) zugeordnet werden<br />

muß. Der Wahrheitswert einer Aussage bestimmt sich aus den Wahrheitswerten <strong>der</strong> Teilaussagen und <strong>der</strong> Verknüpfung<br />

dieser Wahrheitswerte durch den Junktor. Als Wahrheitswerte werden üblicherweise wahr“ (W ) und<br />

”<br />

falsch“ (F ) benutzt. Die Verknüpfungen können mit Hilfe von Wertetabellen dargestellt werden:<br />

”<br />

A ∧ B A ist falsch A ist wahr<br />

B ist falsch falsch falsch<br />

B ist wahr falsch wahr<br />

A ∨ B A ist falsch A ist wahr<br />

B ist falsch falsch wahr<br />

B ist wahr wahr wahr<br />

A ⇒ B A ist falsch A ist wahr<br />

B ist falsch wahr falsch<br />

B ist wahr wahr wahr<br />

A ⇔ B A ist falsch A ist wahr<br />

B ist falsch wahr falsch<br />

B ist wahr falsch wahr<br />

¬A A ist falsch A ist wahr<br />

wahr falsch<br />

Der Wahrheitswert einer Elementaraussage ergibt sich aus <strong>der</strong> betrachteten Welt. Nehmen wir folgende Situationen<br />

an:<br />

Situation 1 Situation 2 Situation 3<br />

A 1 ist wahr A 1 ist falsch A 1 ist falsch<br />

A 2 ist wahr A 2 ist wahr A 2 ist falsch<br />

In Situation 1 sind A 1 und A 2 beide wahr. Ein Blick in die Wertetabellen <strong>der</strong> Junktoren verrät, daß demnach<br />

auch A 3 , A 4 , A 6 und A 8 wahr sind. A 5 ist falsch. Für A 7 wenden wir die Verknüpfung über mehrere Stufen an:<br />

A 1 ⇒ A 2 ist nach Wertetabelle wahr und ¬A 2 ist falsch. Demnach ist (A 1 ⇒ A 2 ) ∧ (¬A 2 ) falsch. ¬A 1 ist ebenso<br />

falsch. Deshalb folgt, daß die Gesamtaussage A 7 falsch ist.<br />

A 3 A 4 A 5 A 6 A 7 A 8<br />

Situation 1 W W F W F W<br />

Situation 2 F W F F F F<br />

Situation 3 F W W W W W<br />

Mathematisch können wir die Situationen als Funktionen auffassen, die den Aussagen jeweils einen Wahrheitswert<br />

zuweisen. Diese Funktionen nennen wir in Zukunft Interpretationen. Wenn eine Formel ϕ unter einer<br />

Interpretation I zu wahr ausgewertet wird, sagen wir: ”<br />

I ist ein Modell von ϕ.“ und schreiben I |= ϕ, beispielsweise<br />

ist die Situation 1 ein Modell <strong>der</strong> Formel A 3 :<br />

Die Situation 2 ist dagegen kein Modell <strong>der</strong> Formel A 6 :<br />

|= A 3


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 54<br />

Eine Formel ϕ heißt erfüllbar, wenn es eine Interpretation gibt, unter <strong>der</strong> ϕ zu wahr ausgewertet wird. In<br />

unserem Beispiel sind die Aussagen A 1 bis A 8 demnach alle erfüllbar. Eine Formel heißt allgemeingültig, wenn<br />

sie unter allen Interpretationen zu wahr ausgewertet wird. Allgemeingültige Formeln werden auch Tautologien<br />

genannt. In unserem Beispiel ist die Aussage A 4 eine Tautologie (wenn angenommen wird, daß nur die drei gegebenen<br />

Situationen existieren.) Da die konkrete Interpretation für den Wahrheitswert einer Tautologie keine Rolle<br />

spielt, läßt man sie weg und schreibt<br />

A 6<br />

|= A 4<br />

Theorien und Ableitungen<br />

Das Wissen über Modelle von Formeln kann benutzt werden, um aus einer gegebenen Menge von Formeln diejenigen<br />

Formeln abzuleiten, die zwingend auch gelten. Wenn beispielsweise bekannt ist, daß die Aussagen A 1 und A 2<br />

beide wahr sind, dann wissen wir auch (aufgrund <strong>der</strong> Definition <strong>der</strong> Junktoren), daß u.a. auch die Formel A 1 ∨ A 2<br />

wahr ist. An<strong>der</strong>s gesprochen: alle Interpretationen, die Modell von A 1 und Modell von A 2 sind, sind auch Modell<br />

von A 1 ∨ A 2 . Ein zweites Beispiel: Alle Modelle <strong>der</strong> Formel A 1 ∧ A 2 sind auch Modell <strong>der</strong> Formel A 1 und Modell<br />

<strong>der</strong> Formel A 2 . An<strong>der</strong>erseits gilt dies nicht zwingend für A 1 ∨ A 2 : in unserem Beispiel sind Situation 1 und<br />

Situation 2 Modelle <strong>der</strong> Formel A 1 ∨ A 2 , die Situation 2 ist aber kein Modell <strong>der</strong> Formel A 1 .<br />

Wenn jedes Modell einer Formelmenge Φ auch Modell einer Formel ψ ist, dann folgt ψ aus Φ, geschrieben<br />

Φ |= ψ. Die Formelmenge Φ nennen wir eine Theorie. Eine Interpretation I ist Modell einer Theorie, wenn sie<br />

Modell je<strong>der</strong> Formel <strong>der</strong> Theorie ist. Wenn eine Theorie mindestens ein Modell hat, nennen wir sie konsistent,<br />

ansonsten inkonsistent.<br />

Wenn eine Theorie (z.B. T = {A 1 , A 2 }) gegeben ist, dann wäre es interessant zu wissen, welche Formeln<br />

auch gelten. Die Folgerungsrelation |= definiert dies zwar, gibt aber keine Möglichkeit zur Bestimmung <strong>der</strong> Menge<br />

vor. Aus diesem Grunde definieren wir eine Ableitungsrelation {ϕ 1 , ..., ϕ n } ⊢ ψ, indem wir Ableitungsregeln<br />

(Inferenzregeln) angeben. Ableitungsregeln werden folgen<strong>der</strong>maßen geschrieben:<br />

ϕ 1 , ..., ϕ n<br />

ψ<br />

Die Formelmenge ϕ 1 , ..., ϕ n stellt die Voraussetzung <strong>der</strong> Regel dar. Wenn jede <strong>der</strong> Formeln <strong>der</strong> Voraussetzung<br />

abgeleitet werden kann, dann kann auch die Konsequenz <strong>der</strong> Regel, die Formel ψ unterhalb des Strichs, abgeleitet<br />

werden. Wichtige Ableitungsregeln sind:<br />

Modus Ponens (Implikationsbeseitigung): Wenn es eine Implikation gibt und die Voraussetzung <strong>der</strong> Implikation<br />

abgeleitet werden kann, dann kann man auch die Konsequenz ableiten:<br />

⊢ ϕ<br />

⊢ ϕ ⇒ ψ<br />

⊢ ψ<br />

Und-Beseitigung: Wenn eine Konjunktion ableitbar ist, dann auch jede <strong>der</strong> Teilformeln:<br />

⊢ ϕ 1 ∧ ... ∧ ϕ n<br />

⊢ ϕ i<br />

Und-Einführung: Wenn eine Menge von Formeln ableitbar ist, dann auch ihre Konjunktion:<br />

⊢ ϕ 1 , ..., ⊢ ϕ n<br />

⊢ ϕ 1 ∧ ... ∧ ϕ n<br />

Unit-Resolution: Wenn eine Disjunktion zusammen mit <strong>der</strong> Negation einer <strong>der</strong> beiden Teilformeln ableitbar<br />

ist, dann ist die an<strong>der</strong>e Teilformel ableitbar:<br />

⊢ ϕ 1 ∨ ϕ 2 , ⊢ ¬ϕ 2<br />

⊢ ϕ 1


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 55<br />

Es gibt noch weitere Ableitungsregeln. In unserem Beispiel läßt sich folgende Ableitung bilden: wir gehen<br />

davon aus, daß Aussage A 4 allgemeingültig ist ( ”<br />

Wenn es regnet, ist die Straße naß.“). Wir sehen aus dem Fenster<br />

und stellen fest, daß es regnet.<br />

∅ ⊢ A 1 (Elementaraussage <strong>der</strong> Welt)<br />

∅ ⊢ A 1 ⇒ A 2 (als Tautologie akzeptiert, ”<br />

Wissen“)<br />

nach Modus Ponens folgt nun<br />

{A 1 , (A 1 ⇒ A 2 )} ⊢ A 2<br />

o<strong>der</strong> an<strong>der</strong>s ausgedrückt: die Straße ist naß.<br />

Anwendungen <strong>der</strong> Aussagenlogik in relationalen <strong>Datenbanken</strong><br />

Wir werden die Erkenntnisse über die Aussagenlogik sowohl in <strong>der</strong> relationalen Algebra als auch im relationalen<br />

Tupelkalkül benutzen, um Bedingungen über Tupeln auszudrücken. Jedes Tupel ist vergleichbar mit einer Situation<br />

im obigen Beispiel. Für unsere Tupel können wir Elementaraussagen definieren, indem wir die Prädikate <strong>der</strong> den<br />

Attributen zugeordneten Datentypen benutzen. Sei z.B. ein Relationenschema ANGEST ELLT ER(Name, W ohnort, Nie<strong>der</strong><br />

gegeben. Den Attributen Name, W ohnort und Nie<strong>der</strong>lassung sei <strong>der</strong> Datentyp ”<br />

Zeichenkette“ zugeordnet. Der<br />

Datentyp ”<br />

Zeichenkette“ verfüge über ein Gleichheitsprädikat =, daß auf lexikalische Gleichheit prüft. Dem Attribut<br />

”<br />

Gehalt“ seien neben einem Gleichheitsprädikat auch Ordnungsprädikate zugeordnet. Dann können<br />

wir folgende Elementaraussagen formulieren:<br />

A 9 : W ohnort = ′ Kiel ′<br />

A 10 : W ohnort = Nie<strong>der</strong>lassung<br />

A 11 : Gehalt > 4000<br />

Wir betrachten folgenden Zustand für das Relationenschema ANGEST ELLT ER (die erste Spalte enthalte<br />

Variablennamen für die einzelnen Tupel, damit wir sie referenzieren können):<br />

Name Wohnort Nie<strong>der</strong>lassung Gehalt<br />

t 1 Müller Kiel Kiel 3500<br />

t 2 Meyer Kiel Rendsburg 4000<br />

t 3 Petersen Flensburg Flensburg 4300<br />

t 4 Schmidt Lübeck Hamburg 4400<br />

Die vier Tupel entsprechen den vier möglichen Situationen ( mögliche Welten“, engl. possible worlds“.) Wir<br />

” ”<br />

erhalten folgende Wahrheitswerte:<br />

A 9 A 10 A 11 A 10 ∧ A 11<br />

t 1 W W F F<br />

t 2 W F F F<br />

t 3 F W W W<br />

t 4 F F W F<br />

Demnach ist t 1 ein Modell <strong>der</strong> Aussagen A 9 und A 10 (t 1 |= A 9 , t 1 |= A 10 ). Das Tupel t 3 ist z.B. ein Modell<br />

<strong>der</strong> Aussagen A 10 , A 11 und A 10 ∧ A 11 (t 3 |= A 10 , t 3 |= A 11 , t 3 |= (A 10 ∧ A 11 ).)<br />

Prädikatenlogik erster Stufe<br />

Die Aussagenlogik erlaubt es nicht, Aussagen über Mengen von möglichen Welten zu treffen. Wenn wir unser<br />

Angestellten-Relationenschema aus dem letzten Abschnitt als Beispiel nehmen, dann kann die Aussage ”<br />

Alle Angestellten<br />

<strong>der</strong> Hamburger Nie<strong>der</strong>lassung verdienen mehr als 3000 e.“ nicht mit Hilfe <strong>der</strong> Aussagenlogik formuliert<br />

werden 9 . Aus diesem Grunde erweitern wir unseren Formelbegriff um folgende Konstrukte:<br />

9 Die Aussage kann natürlich als Elementaraussage über den Nie<strong>der</strong>lassungen formuliert werden. Allerdings ist es dann nicht mehr<br />

möglich, Zusammenhänge z.B. zum Gehalt eines einzelnen Angestellten <strong>der</strong> Nie<strong>der</strong>lassung herzustellen.


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 56<br />

• Wir führen Variablen ein. 10 Wir benutzen hier getypte Variablen (analog zur Diskussion über die Attribute<br />

des relationalen Datenmodells.)<br />

• Es werden Prädikate definiert. Die Aussagen <strong>der</strong> Aussagenlogik entsprechen 0-stelligen Prädikaten, z.B.<br />

EsRegnet(). Wir erlauben aber jetzt auch Prädikate höherer Stelligkeit, z.B. IstNaß(x) o<strong>der</strong> MuendetIn(x, y),<br />

wobei <strong>der</strong> Wertebereich <strong>der</strong> Variablen x und y die Menge aller Straßen ist.<br />

• Weiterhin existieren Quantoren: sei ϕ eine Formel <strong>der</strong> Prädikatenlogik erster Stufe. Dann sind auch<br />

(∃x)(ϕ)<br />

(∀x)(ϕ)<br />

es gibt“<br />

”<br />

für alle“<br />

”<br />

Formeln <strong>der</strong> Prädikatenlogik erster Stufe, wobei die Variable x in ϕ ”<br />

frei“ sein muß: sie darf in ϕ noch nicht<br />

an einen Quantor (∃ o<strong>der</strong> ∀) gebunden sein.<br />

Mit Hilfe <strong>der</strong> Quantoren lassen sich jetzt Aussagen über Mengen von Objekten machen, beispielsweise ”<br />

Es<br />

gibt eine nasse Straße“:<br />

o<strong>der</strong> ”<br />

Jede Straße mündet in eine an<strong>der</strong>e Straße.“<br />

(∃x)(IstNaß(x))<br />

(∀x)((∃y)(MuendetIn(x, y)))<br />

Die üblichen Junktoren <strong>der</strong> Aussagenlogik bleiben uns erhalten: ”<br />

Wenn es regnet, sind alle nichtüberdachten<br />

Straßen naß.“:<br />

EsRegnet() ⇒ (∀x)((¬Ueberdacht(x)) ⇒ IstNaß(x))<br />

Nicht alle Variablen müssen an Quantoren gebunden sein: ”<br />

Die nassen Straßen“<br />

IstNaß(x)<br />

Eine Interpretation einer Formel <strong>der</strong> Prädikatenlogik erster Stufe ist eine Funktion, die allen Prädikaten eine<br />

Ausprägung (Extension) zuordnet, d.h. eine Menge von Tupeln, die das Prädikat erfüllen. 11<br />

Eine Variablenbelegung ϱ ordnet je<strong>der</strong> Variablen einen Wert ihres Wertebereichs zu. Damit können wir die |=<br />

- Relation definieren:<br />

I, ϱ |= P (x 1 , ..., x n ) gdw. (ϱ(x 1 ), ..., ϱ(x n )) ist in <strong>der</strong> durch I gegebenen Ausprägung des Prädikats P enthalten.<br />

Beispiel: Betrachten wir die Formel IstNaß(x). Sei die Menge aller Straßen S = {Olshausenstr, W estring, W aitzstr, Os<br />

Die Interpretation I weise dem Prädikat IstNaß die Menge {Olshausenstr, W estring, W aitzstr} zu. Die Variablenbelegung<br />

ϱ 1 weise <strong>der</strong> Variablen x den Wert W estring zu. Dann gilt I, ϱ 1 |= IstNaß(x), da ϱ 1 (x) =<br />

W estring und W estring ∈ {Olshausenstr, W estring, W aitzstr}. Wenn wir die Variablenbelegung ϱ 2 betrachten,<br />

die <strong>der</strong> Variablen x den Wert Ostring zuweist, dann gilt I, ϱ 2 IstNaß(x), da Ostring /∈ {Olshausenstr, W estring<br />

Wenn wir aber die Interpretation I 2 betrachten, die dem Prädikat IstNaß die Menge {Olshausenstr, W estring, W aitzstr, Ost<br />

zuordnet, dann gilt I 2 , ϱ 2 |= IstNaß(x).<br />

Für die Junktoren ist die |= - Relation entsprechend <strong>der</strong> Aussagenlogik definiert. Für die Quantoren gilt:<br />

I, ϱ |= (∀x)(ϕ) gdw. I, ϱ ′ |= ϕ für alle möglichen ϱ ′ , die sich von ϱ höchstens in <strong>der</strong> Belegung von x unterscheiden.<br />

10 W ohnort, Nie<strong>der</strong>lassung und Gehalt in den Formeln <strong>der</strong> Aussagenlogik sind keine Variablen in diesem Sinne, da die Formel<br />

jeweils immer für eine ganz bestimmte Welt (für ein ganz bestimmtes Tupel) ausgewertet wurde; dort sind den Attributen aber eindeutige<br />

Werte zugeordnet.<br />

11 Korrekterweise ist die Interpretation ein Tripel bestehend aus dem Wertebereich, <strong>der</strong> Belegung <strong>der</strong> Konstantensymbole und <strong>der</strong> Prädikatsausprägung,<br />

aber dies vernachlässigen wir hier.


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 57<br />

I, ϱ |= (∃x)(ϕ) gdw. es gibt eine Variablenbelegung ϱ ′ , die sich von ϱ höchstens in <strong>der</strong> Belegung von x<br />

unterscheidet, so daß gilt: I, ϱ ′ |= ϕ.<br />

Wenn I, ϱ |= ϕ für alle Belegungen ϱ gilt, dann schreiben wir auch I |= ϕ und sagen I erfüllt ϕ bzw. I<br />

ist ein Modell von ϕ. Die Definitionen <strong>der</strong> Erfüllbarkeit und Allgemeingültigkeit orientieren sich an denen <strong>der</strong><br />

Aussagenlogik.<br />

Wir werden die Prädikatenlogik erster Stufe im Kontext des relationalen Tupelkalküls benutzen, um Anfragen<br />

an Datenbanksysteme zu formulieren.<br />

Mehrwertige Logiken<br />

Bisher haben wir zweiwertige Logiken betrachtet: eine Aussage war immer entwe<strong>der</strong> wahr o<strong>der</strong> falsch. Es ist<br />

jedoch nicht in allen Situationen möglich, diese Entscheidung zu treffen: manchmal ist eine Aussage ”<br />

ein bisschen<br />

wahr und ein bisschen falsch“, manchmal wissen wir nicht, ob eine Aussage wahr o<strong>der</strong> falsch ist. Betrachten wir<br />

z.B. folgende Personen:<br />

Anna Kristina Joe Sandra Thomas<br />

blondes Haar rotes Haar Glatze Welche Haarfarbe? Glatze o<strong>der</strong> Haare?<br />

Anna hat offensichtlich blondes Haar. Kristina hat rotes Haar und Joe trägt eine Glatze. Sandra färbt sich öfters<br />

die Haare, deshalb weiß man es nie so genau, welche Haarfarbe sie momentan hat. Da man Thomas nur mit seinem<br />

Helm sieht, weiß man nicht, ob er eine Glatze trägt bzw. welche Farbe seine Haare haben. Wenn wir eine Relation<br />

mit den Haarfarben <strong>der</strong> Personen aufschreiben, dann kann man für Anna und Kristina eindeutig ’blond’ bzw. ’rot’<br />

eintragen. Joe hat keine Haare und demnach auch keine Haarfarbe. Bei Sandra kennen wir die Farbe nicht und<br />

bei Thomas sind wir uns nicht sicher, ob er eine Haarfarbe hat. Unsere ”<br />

Unwissenheit“ können wir mit einem<br />

null-Wert im Wertebereich des Attributs Haarfarbe ausdrücken:<br />

Name<br />

Anna<br />

Kristina<br />

Joe<br />

Sandra<br />

Thomas<br />

Haarfarbe<br />

blond<br />

rot<br />

null<br />

null<br />

null<br />

Angenommen, in <strong>der</strong> ”<br />

realen Welt“ gibt es nur die Haarfarben blond, rot, braun und schwarz. Wir können eine<br />

Aussage A 12 formulieren: Haarfarbe = ′ blond ′ ∨Haarfarbe = ′ rot ′ ∨Haarfarbe = ′ braun ′ ∨Haarfarbe = ′<br />

schwarz ′ . Offensichtlich gilt:<br />

Name : Anna, Haarfarbe : blond |= A 12<br />

Name : Kristina, Haarfarbe : rot |= A 12<br />

Obwohl wir alle möglichen Haarfarben aufzählen, fallen Joe, Sandra und Thomas unter den Tisch. Dies ist in<br />

<strong>der</strong> Tatsache begründet, daß <strong>der</strong> null-Wert <strong>der</strong> Haarfarbe ein künstlicher Wert ist, <strong>der</strong> keine Entsprechung in <strong>der</strong><br />

realen Welt“ hat. Er vermischt das konkrete Datum Haarfarbe mit dem Wissen über die Existenz des Datums<br />

”<br />

Haarfarbe.<br />

Wir können eine Aussage A 13 definieren: ¬Haarfarbe = ′ blond ′ . Für Kristina und Joe ergibt dies das<br />

gewünschte Ergebnis. Bei Sandra und Thomas wissen wir aber nicht, ob sie evtl. doch blond sind. Wenn dies<br />

<strong>der</strong> Fall ist, wäre die Antwort unseres Systems falsch.


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 58<br />

Aus diesem Grunde kann die klassische zweiwertige Logik erweitert werden. Der hier vorgestellte Ansatz<br />

wurde von Jan Łukasiewicz 1920 eingeführt. Es wird ein dritter Wahrheitswert definiert, <strong>der</strong> zwischen wahr“ und ”<br />

” falsch“ angesiedelt ist. Der Wahrheitsgehalt dieses Werts wird als möglich, aber nicht bewiesen“ gedeutet. Wir<br />

”<br />

könnten also das Prädikat =“ des Datentyps Haarfarbe so verän<strong>der</strong>n:<br />

”<br />

=(x,y) blond rot schwarz braun null<br />

blond W F F F M<br />

rot F W F F M<br />

schwarz F F W F M<br />

braun F F F W M<br />

null M M M M M<br />

Das Prädikat sagt jetzt folgendes aus: die Werte blond, rot, schwarz und braun werden untereinan<strong>der</strong> im üblichen<br />

Sinne verglichen. Wenn einer <strong>der</strong> Werte null ist, dann ist das Vergleichsergebnis möglicherweise wahr, möglicherweise<br />

aber auch falsch.<br />

Wir müssen natürlich die Wertetabellen <strong>der</strong> Junktoren anpassen:<br />

A ∧ B A ist falsch A ist möglich A ist wahr<br />

B ist falsch falsch falsch falsch<br />

B ist möglich falsch möglich möglich<br />

B ist wahr falsch möglich wahr<br />

Wenn eine <strong>der</strong> Teilaussagen falsch ist, dann kann die Gesamtaussage nicht wahr werden. Wenn beide Teilaussagen<br />

wahr sind, ist die Gesamtaussage wahr. Wenn eine Teilaussage wahr und die zweite Teilaussage möglicher-<br />

”<br />

weise wahr ist, dann ist die Gesamtaussage möglicherweise wahr. Wenn beide Teilaussagen möglicherweise wahr<br />

sind, ist die Gesamtaussage möglicherweise wahr.“<br />

A ∨ B A ist falsch A ist möglich A ist wahr<br />

B ist falsch falsch möglich wahr<br />

B ist möglich möglich möglich wahr<br />

B ist wahr wahr wahr wahr<br />

Wenn eine <strong>der</strong> Teilaussagen wahr ist, wird die Gesamtaussage wahr. Wenn beide Teilaussagen falsch sind, ist<br />

”<br />

die Gesamtaussage falsch. Sonst ist die Gesamtaussage möglich.“<br />

Es gibt zwei Arten <strong>der</strong> Negation: die starke Negation ¬A und die schwache Negation ∼ A:<br />

¬A A ist falsch A ist möglich A ist wahr<br />

wahr möglich falsch<br />

∼ A A ist falsch A ist möglich A ist wahr<br />

wahr wahr falsch<br />

Aufbauend auf den beiden Negationen gibt es zwei Implikationen: A ⇒ B = def ¬A ∨ B, A → B = def ∼<br />

A ∨ B. Man beachte, daß die Tautologien <strong>der</strong> klassischen Logik (z.B. A ∨ ¬A) in <strong>der</strong> dreiwertigen Logik nicht<br />

unbedingt gelten müssen.<br />

Aufbauend auf <strong>der</strong> mehrwertigen Logik lässt sich jetzt z.B. die Anfrage Wer hat ganz sicher keine blonden<br />

”<br />

Haare?“ von <strong>der</strong> Anfrage Wer hat möglicherweise keine blonden Haare?“ unterscheiden.<br />

”<br />

Die hier vorgestellte dreiwertige Logik hat immer noch Probleme: Auf die Anfrage Wer hat möglicherweise<br />

”<br />

blonde Haare?“ qualifiziert sich Joe immer noch, obwohl er als Glatzenträger mit Sicherheit keine blonden Haare<br />

hat. Allerdings fällt er bei <strong>der</strong> Anfrage Wer hat mit Sicherheit keine blonden Haare?“ unter den Tisch. Deshalb<br />

”<br />

kann die dreiwertige Logik erweitert werden, um verschiedene Arten von null-Werten zu unterstützen. In unserem<br />

Beispiel unterscheidet sich die Bedeutung des null-Werts für Joe, Sandra und Thomas: bei Joe drückt die null<br />

aus, daß es keinen Wert für die Haarfarbe gibt, bei Sandra, daß die Haarfarbe unbekannt ist und bei Thomas, daß<br />

unbekannt ist, ob es einen Wert für die Haarfarbe gibt. Mit diesen Erweiterungen werden wir uns hier aber nicht<br />

beschäftigen.


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 59<br />

Anhang<br />

12<br />

Einführung<br />

Mit SQL existiert eine standardisierte Sprache, um auf Daten eines relationalen Datenbanksystems zuzugreifen. Die<br />

Art und Weise, wie SQL-Anfragen an das System übermittelt werden, ist jedoch für jedes Datenbankmanagementsystem<br />

spezifisch. Oftmals unterscheiden sich sogar verschiedene Versionen desselben <strong>DB</strong>MS in den verwendeten<br />

Schnittstellen.<br />

Eine Anwendung, die auf ein <strong>DB</strong>S zugreifen möchte, muss die Kommunikationsprotokolle des <strong>DB</strong>MS kennen.<br />

Die Hersteller bieten deshalb für die gängigen Programmiersprachen und Laufzeitumgebungen Bibliotheken an, die<br />

den Datenbankzugriff ermöglichen. In PHP kann man beispielsweise auf eine MySQL-Datenbank folgen<strong>der</strong>maßen<br />

zugreifen (die Variablen sind selbsterklärend, die Fehlerbehandlung wurde weggelassen):<br />

$conn = mysql_connect($host,$user,$password);<br />

mysql_select_db($db,$conn);<br />

$result = mysql_query("select HOTEL_CODE,HOTEL_NAME from ACCOMMODATION");<br />

while($row = mysql_fetch_row($result))<br />

{<br />

echo "Code: $row[0], Name: $row[1]";<br />

}<br />

mysql_close($conn);<br />

Wenn diese Anwendung z.B. nach PostgreSQL portiert werden soll, so müssen alle mysql *-Aufrufe z.B.<br />

durch entsprechende pg *-Aufrufe des PostgreSQL-Moduls ersetzt werden.<br />

Um anwendungsseitig einen (relativ) <strong>DB</strong>MS-neutralen Zugriffsmechanismus auf <strong>Datenbanken</strong> zu ermöglichen,<br />

wurden diverse Frameworks spezifiziert, z.B. die Open Database Connectivity (O<strong>DB</strong>C), ActiveX Data Objects<br />

(ADO) o<strong>der</strong> die Java Database Connectivity (J<strong>DB</strong>C). Mit letzterem wollen wir uns hier beschäftigen.<br />

Um ein mögliches Missverständnis auszuschließen: J<strong>DB</strong>C ist kein Framework, daß die systemspezifische Unterstützung<br />

verschiedener SQL-Dialekte abstrahiert. Die J<strong>DB</strong>C-Infrastruktur sorgt lediglich dafür, daß eine SQL-<br />

Anfrage von <strong>der</strong> Anwendung standardisiert an das <strong>DB</strong>S übergeben und das Ergebnis zurückgeliefert wird. J<strong>DB</strong>C<br />

sorgt nicht dafür, daß z.B. die in MySQL optionale from-Klausel beim Zugriff auf an<strong>der</strong>e Systeme automatisch<br />

ergänzt wird. ”<br />

SQL Tuning“ für spezifische Systeme bleibt weiterhin Aufgabe des Programmierers.<br />

Grundgerüst eines J<strong>DB</strong>C-basierten Programms<br />

Abbildung 3 zeigt den Grobaufbau einer J<strong>DB</strong>C-basierten Anwendung. Sie besteht aus 3 Schichten:<br />

• Anwendungslogik: Sie definiert die Verarbeitungsregeln <strong>der</strong> Geschäftsprozesse.<br />

• J<strong>DB</strong>C-Datenbanktreiber: Er kapselt die Spezifika des Datenbanksystems und stellt <strong>der</strong> Anwendungslogik<br />

die Daten <strong>der</strong> Datenbank mit Hilfe einer standardisierten Schnittstelle zur Verfügung.<br />

• Datenbank: Speichert die Daten. Der Treiber kommuniziert mit <strong>der</strong> Datenbank über ein <strong>DB</strong>MS-spezifisches<br />

Protokoll.<br />

Aus Sicht des Java-Programmierers ist ein J<strong>DB</strong>C-Datenbanktreiber eine Bibliothek bestehend aus einer Reihe<br />

von Klassen. Die Klassen implementieren die Interfaces <strong>der</strong> Standard-Packages java.sql und javax.sql.<br />

Diese Interfaces erlauben das datenbankunabhängige Programmieren mit Hilfe von J<strong>DB</strong>C: die Anwendung ”<br />

sieht“<br />

nur ein java.sql-Interface. Welche Klasse aus welchem Treiber letztlich instanziiert wurde, bleibt verborgen.<br />

Der Zugriff auf eine Datenbank über J<strong>DB</strong>C innerhalb eines Java-Programms lässt sich in einzelne Phasen<br />

aufteilen, die nacheinan<strong>der</strong> ausgeführt werden müssen, Abbildung 4 zeigt eine Übersicht.<br />

12 Dieser Anhang wurde von G. Fiedler erstellt.


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 60<br />

.<br />

.<br />

Applikationslogik<br />

.<br />

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .<br />

.<br />

.<br />

.<br />

.<br />

.<br />

.<br />

J<strong>DB</strong>C-<br />

Treiber<br />

.<br />

J<strong>DB</strong>C-<br />

Treiber<br />

.<br />

J<strong>DB</strong>C-<br />

Treiber<br />

.<br />

.<br />

.<br />

O<strong>DB</strong>C-<br />

Treiber<br />

.<br />

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .<br />

.<br />

.<br />

.<br />

<strong>DB</strong>2<br />

.<br />

Oracle<br />

.<br />

CSV-Datei<br />

.<br />

Abbildung 3: Aufbau einer J<strong>DB</strong>C-basierten Anwendung<br />

1. Laden des Treibers:<br />

In dieser Phase werden die Klassen des J<strong>DB</strong>C - Treibers dynamisch in die Anwendung eingebunden und<br />

registriert.<br />

<strong>2.</strong> Herstellen <strong>der</strong> Verbindung:<br />

Der Treiber baut eine Verbindung zum <strong>DB</strong>MS auf.<br />

3. Erzeugen eines Statements:<br />

Statements sind die J<strong>DB</strong>C-Repräsentation für SQL-Anweisungen. Bevor eine SQL-Anfrage gestartet werden<br />

kann, muss sie in ein Statement ”<br />

verpackt“ werden.<br />

4. Ausführen des Statements:<br />

Die SQL-Anfrage wird an das <strong>DB</strong>MS übermittelt und dort ausgeführt. Die Resultate werden zurückgeliefert.<br />

5. Auswertung <strong>der</strong> Ergebnisse:<br />

Über die Methoden des Interfaces java.sql.ResultSet kann das Ergebnis einer Anfrage ausgewertet<br />

werden.<br />

6. Schließen <strong>der</strong> Verbindung:<br />

um nicht weiter benötigte Ressourcen freizugeben.<br />

Die Phasen im Detail<br />

Dieser Abschnitt verdeutlicht die einzelnen Phasen eines J<strong>DB</strong>C-Zugriffs anhand von Codebeispielen und Abbildungen.<br />

Grundlage bildet wie<strong>der</strong> unsere 3-Schichten-Anwendung:


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 61<br />

Laden des Treibers<br />

♣<br />

♣<br />

♣<br />

Herstellen <strong>der</strong> Verbindung<br />

zum <strong>DB</strong>MS<br />

♣<br />

Erzeugen eines<br />

Statement-Objekts<br />

♣<br />

♣<br />

♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣<br />

Ausführen<br />

einer Anfrage<br />

♣♣♣♣♣♣♣♣♣♣♣♣ ♣<br />

Ausführen<br />

eines Updates<br />

♣<br />

Auswertung<br />

<strong>der</strong> Ergebnisse<br />

♣<br />

♣<br />

Schließen<br />

<strong>der</strong> Verbindung<br />

Abbildung 4: Phasen des Datenbankzugriffs<br />

.<br />

.<br />

Applikationslogik<br />

.<br />

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .<br />

.<br />

.<br />

<strong>DB</strong>2-Treiber<br />

.<br />

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .<br />

.<br />

<strong>DB</strong>2<br />

.<br />

Laden des Treibers<br />

Wie bereits angedeutet, ist ein J<strong>DB</strong>C-Datenbanktreiber nichts an<strong>der</strong>es als eine Bibliothek diverser Java-Klassen,<br />

welche die Interfaces aus java.sql und javax.sql implementieren. Je<strong>der</strong> Treiber enthält als Repräsentanten<br />

eine ”<br />

Hauptklasse“, die das Interface java.sql.Driver implementiert. Über diese Klasse wird <strong>der</strong> Treiber


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 62<br />

identifiziert und angesprochen.<br />

Eine zentrale J<strong>DB</strong>C-Komponente ist <strong>der</strong> Treibermanager. Er wird durch die Klasse java.sql.DriverManager<br />

repräsentiert und ist zuständig für die Verwaltung und den Zugriff auf die Datenbanktreiber. Ein Treiber steht <strong>der</strong><br />

Anwendung erst zur Verfügung, wenn er sich beim Treibermanager registriert hat.<br />

Das dynamische Laden eines Treibers gestaltet sich genauso wie das Laden je<strong>der</strong> an<strong>der</strong>en beliebigen Java-<br />

Klasse. Angenommen, wir möchten den Treiber für <strong>DB</strong>2-<strong>Datenbanken</strong> laden. Die ”<br />

Hauptklasse“ des J<strong>DB</strong>C-Treibers<br />

hat den Namen com.ibm.db<strong>2.</strong>jcc.<strong>DB</strong>2Driver:<br />

try Class.forName(com.ibm.db<strong>2.</strong>jcc.<strong>DB</strong>2Driver“).newInstance(); catch(ClassNotFoundException e) // Fehlerbehandlung,<br />

falls Klasse nicht gefunden wurde<br />

Die Treiberklasse sorgt automatisch für eine Registrierung beim Treibermanager. Das Laden des Treibers muss<br />

nur einmal während <strong>der</strong> Initialisierungsphase durchgeführt werden, <strong>der</strong> Treiber steht bis zum Ende <strong>der</strong> Anwendung<br />

zur Verfügung:<br />

.<br />

.<br />

Applikationslogik<br />

.<br />

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .<br />

.<br />

.<br />

<strong>DB</strong>2-Treiber<br />

.<br />

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .<br />

.<br />

<strong>DB</strong>2<br />

.<br />

Herstellen <strong>der</strong> Verbindung<br />

Nachdem <strong>der</strong> Datenbank-Treiber in die Anwendung integriert wurde, kann die Verbindung zur Datenbank geöffnet<br />

werden. Dafür sind die folgenden Informationen von Bedeutung:<br />

• Welcher Treiber soll benutzt werden?<br />

• Wie heißt die Datenbank und wo befindet sie sich?<br />

• Mit welchen Daten authentifiziere ich mich gegenüber <strong>der</strong> Datenbank?<br />

• ...<br />

Das Öffnen <strong>der</strong> Verbindung wird durch den Treibermanager und dessen statische Methode getConnection()<br />

veranlasst. Diese Methode liefert ein Objekt zurück, dessen Klasse das Interface java.sql.Connection implementiert.<br />

Die oben genannten Daten werden <strong>der</strong> Methode in Form einer URL (uniform resource locator) übergeben.<br />

Diese URL hat die folgende standardisierte Form:<br />

jdbc::<br />

Über die Zeichenkette wird <strong>der</strong> gewünschte Treiber spezifiziert. Der Inhalt von <br />

hängt vom konkreten Treiber ab. Der <strong>DB</strong>2-Treiber erwartet beispielsweise folgende URL:<br />

jdbc:db2://:/:


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 63<br />

Die Kombination aus und gibt dabei den Server an, auf dem sich die Datenbank befindet,<br />

spezifiziert den Namen <strong>der</strong> Datenbank. Zusätzliche Parameter können in <strong>der</strong> Form =;<br />

nach dem Doppelpunkt angegeben werden. Für Verbindungsparameter sei auf das <strong>DB</strong>2-Handbuch verwiesen.<br />

Angenommen, <strong>der</strong> Nutzer joe (Passwort: foo) möchte die <strong>DB</strong>2-Datenbank namens Personal auf dem<br />

Rechner dbserver nutzen. Das <strong>DB</strong>MS ist über Port 1234 erreichbar.<br />

Es gibt 3 verschiedene Varianten <strong>der</strong> DriverManager.getConnection-Methode:<br />

• DriverManager.getConnection(String url):<br />

Der allgemeine Fall. Alle Daten müssen gemäß <strong>der</strong> oben genannten Vorschrift in eine URL verpackt werden:<br />

String url = “jdbc:db2://dbserver:1234/Personal:user=joe;password=foo;“;<br />

Connection conn = DriverManager.getConnection(url);<br />

• DriverManager.getConnection(String url, Properties info):<br />

Der Methode wird zusätzlich ein assoziatives Array info übergeben, welches die Parameter aufnehmen<br />

kann, die normalerweise nach dem Fragezeichen <strong>der</strong> URL stehen würden. Sinnvoll ist diese Trennung, wenn<br />

diese Parameter dynamisch generiert werden. Dann entfällt die umständliche Kodierung <strong>der</strong> URL: Properties<br />

props = new Properties(); props.put(üser“,“joe“); props.put(password“,foo“); String url = “jdbc:db2://dbserver:1234/Person<br />

Connection conn = DriverManager.getConnection(url,props);<br />

• DriverManager.getConnection(String url, String user, String password):<br />

Analog zur <strong>2.</strong> Variante, falls als Parameter nur Nutzername und Passwort benötigt werden: String url =<br />

“jdbc:db2://dbserver:1234/Personal“;<br />

Connection conn = DriverManager.getConnection(url,“joe“,foo“);<br />

Nach Abschluß dieser Phase besteht eine Kommunikationsverbindung zwischen <strong>der</strong> Anwendung und <strong>der</strong> Datenbank:<br />

.<br />

.<br />

Applikationslogik<br />

.<br />

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .<br />

.<br />

.<br />

<strong>DB</strong>2-Treiber<br />

<br />

.<br />

<br />

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .<br />

<br />

.<br />

<strong>DB</strong>2<br />

.<br />

<strong>2.</strong>4.8 Datasources<br />

In realen Umgebungen ist es normalerweise notwendig, den Verbindungsaufbau weiter zu abstrahieren. In <strong>der</strong> URL<br />

sind z.B. <strong>der</strong> Datenbankserver und <strong>der</strong> Name <strong>der</strong> Datenbank vermerkt. Eine Anwendung wird i.d.R. in verschiedenen<br />

Umgebungen eingesetzt, und es kann relativ häufig passieren, daß sich die Konfigurationsparameter <strong>der</strong><br />

Datenbank än<strong>der</strong>n. Außerdem ist vielleicht eine zentrale Konfiguration für verschiedene Anwendungen sinnvoll,<br />

die alle parallel auf ein Datenbanksystem zugreifen möchten.


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 64<br />

Seit <strong>der</strong> J<strong>DB</strong>C-Version <strong>2.</strong>0 existiert ein neues Interface namens javax.sql.DataSource, welches sich<br />

dieses Problems annimmt. DataSource-Objekte kapseln eine Datenquelle. Über die Methode getConnection<br />

des DataSource-Interfaces kann man sich eine vorkonfigurierte Verbindung zu dieser Datenquelle geben lassen.<br />

DataSources spielen ihre Vorteile insbeson<strong>der</strong>e in J2EE-Umgebungen aus. Dort übernimmt <strong>der</strong> Anwendungsserver<br />

die zentrale Verwaltung aller bekannten Datenquellen. Über einen Verzeichnisdienst (JNDI, ”<br />

Gelbe Seiten“)<br />

kann eine Anwendung auf eine Datenquelle des Anwendungsservers über einen Namen zugreifen. Wenn sich die<br />

physischen Parameter <strong>der</strong> Datenquelle än<strong>der</strong>n (z.B. wenn die Datenbank auf einen neuen Rechner umzieht), dann<br />

muß diese Än<strong>der</strong>ung nur zentral im Anwendungsserver durchgeführt werden.<br />

Die Benutzung von Datenquellen hat einen weiteren entscheidenden Vorteil: das Öffnen einer Verbindung ist<br />

ein relativ kostenintensiver Prozeß, <strong>der</strong> einige Sekunden dauern kann. Die zentrale Verwaltung von Datenbankverbindungen<br />

erlaubt die Implementierung des ”<br />

Pooling“-Patterns: Die Datenquelle verwaltet einen Pool von offenen<br />

Verbindungen. Wenn eine Anwendung eine Verbindung anfor<strong>der</strong>t, dann wird keine neue Verbindung geöffnet, son<strong>der</strong>n<br />

sie bekommt eine <strong>der</strong> offenen Verbindungen zugeteilt, die sich im Pool befinden. Wenn die Anwendung die<br />

Verbindung schließt, dann wird die Verbindung wie<strong>der</strong> als ”<br />

frei“ markiert. Durch diesen Mechanismus, <strong>der</strong> einigen<br />

vielleicht aus dem Kontext von Prozessen und Threads bekannt ist, wird eine erhebliche Performance-Steigerung<br />

erreicht.<br />

Erzeugen eines Statements<br />

SQL-Anfragen werden unter J<strong>DB</strong>C in Statement-Objekte eingekapselt. Bevor eine Anfrage ausgeführt werden<br />

kann, muß ein <strong>der</strong>artiges Objekt erzeugt werden. Dies geschieht durch Aufruf <strong>der</strong> createStatement-Methode<br />

des im vorherigen Schritt erzeugten Connection-Objekts:<br />

Statement stmt = conn.createStatement();<br />

.<br />

.<br />

Applikationslogik<br />

.<br />

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .<br />

.<br />

.<br />

<strong>DB</strong>2-Treiber<br />

<br />

<br />

.<br />

stmt<br />

.<br />

<br />

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .<br />

<br />

.<br />

<strong>DB</strong>2<br />

.<br />

Neben einfachen SQL-Anfragen, wie wir sie hier betrachten, können über Statement-Objekte auch spezielle<br />

vorcompilierte Anfragen (prepared statements) und stored procedures ausgeführt werden. Außerdem läßt sich über<br />

die Statement-Objekte die Rückgabe des Ergebnisses steuern. Zu beachten ist: ein einzelnes Statement kann<br />

nicht mehrere SQL-Anfragen gleichzeitig verwalten. Ergebnisse müssen verarbeitet werden, bevor mit diesem<br />

Statement-Objekt eine neue Anfrage gestellt wird.<br />

Ausführen eines Statements<br />

Das Statement-Objekt stellt Methoden zum Ausführen von SQL-Anweisungen bereit. Aufgrund <strong>der</strong> unterschiedlichen<br />

Bedürfnisse werden zwei verschiedene Anweisungsarten unterschieden: Anfragen und Updates.


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 65<br />

Anfragen sind SQL-Anweisungen, die ein Ergebnis zurückliefern, typischerweise select - Anweisungen. Sie<br />

werden über die executeQuery-Methode des Statement-Objekts ausgeführt, diese Methode nimmt die Anfrage<br />

als Parameter in Textform entgegen und liefert das Ergebnis in einem ResultSet-Objekt zurück:<br />

ResultSet result = stmt.executeQuery(SSELECT * FROM staff“);<br />

.<br />

.<br />

Applikationslogik<br />

.<br />

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .<br />

.<br />

<strong>DB</strong>2-Treiber<br />

<strong>DB</strong>2<br />

result<br />

<br />

.<br />

stmt<br />

.<br />

♣♣<br />

<br />

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .<br />

. .<br />

<br />

.<br />

♣♣ ♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣ ♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣ ♣<br />

.<br />

♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣♣ ♣<br />

♣ ♣♣♣♣♣♣♣♣♣♣ ♣<br />

.<br />

♣<br />

♣<br />

SELECT * FROM staff<br />

.<br />

Updates entsprechen den drei DML-Anweisungen insert, update und delete. Sie werden über die<br />

executeUpdate-Methode des Statement-Objekts ausgeführt. Diese Methode liefert als Ergebnis die Anzahl<br />

<strong>der</strong> durch das Update betroffenen Tupel zurück, vorausgesetzt <strong>der</strong> Treiber sowie das <strong>DB</strong>MS unterstützen dies:<br />

stmt.executeUpdate( ÜPDATE staff SET salary=3000 WHERE name=’Joe Hacker’“);<br />

.<br />

.<br />

Applikationslogik<br />

.<br />

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .<br />

.<br />

<strong>DB</strong>2-Treiber<br />

♣<br />

♣<br />

♣ ♣ ♣ ♣ ♣ ♣ ♣ ♣ ♣<br />

stmt<br />

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .<br />

.<br />

.<br />

.<br />

.<br />

.<br />

♣<br />

.<br />

<strong>DB</strong>2<br />

.<br />

. .<br />

UPDATE staff SET salary=3000<br />

WHERE name=’Joe Hacker’<br />

Auswertung <strong>der</strong> Ergebnisse<br />

Wurde eine Anfrage ausgeführt, muß in dieser Phase das zurückgelieferte ResultSet ausgewertet werden. Dies<br />

geschieht nach dem Iterator-Pattern. Das Objekt besitzt einen internen Zeiger auf das jeweils aktuelle Tupel <strong>der</strong><br />

Ergebnismenge. Über die Methode next() wird dieser Zeiger auf das jeweils nächste Tupel gesetzt. Ist kein Tupel<br />

mehr vorhanden, so liefert die next-Methode den boolschen Wert false zurück. Zu Beginn steht <strong>der</strong> Zeiger vor<br />

dem ersten Tupel.<br />

Auf die einzelnen Attribute des aktuellen Tupels kann über die getXXX-Methoden des ResultSet-Objekts<br />

zugegriffen werden. XXX steht dabei für die Namen <strong>der</strong> Standarddatentypen, z.B. String o<strong>der</strong> Double. Diese<br />

Methoden erwarten entwe<strong>der</strong> den Index des Attributs (Achtung: die Zählung beginnt bei 1!) o<strong>der</strong> dessen Namen.<br />

Es wird vorausgesetzt, daß <strong>der</strong> Typ des jeweiligen Attributs bekannt ist.<br />

while( result.next() ) System.out.println( result.getString(name“)+“: “+ Double.toString(result.getDouble(ßalary“)));


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 66<br />

Schließen <strong>der</strong> Verbindung<br />

Wird eine Datenbank-Verbindung nicht mehr benötigt, kann sie durch einen Aufruf <strong>der</strong> close-Methode des<br />

Connection-Objekts geschlossen werden, um Systemressourcen freizugeben. Gleiches gilt für Resultsets und<br />

Statements:<br />

result.close(); stmt.close(); conn.close();<br />

.<br />

.<br />

Applikationslogik<br />

.<br />

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .<br />

.<br />

.<br />

<strong>DB</strong>2-Treiber<br />

.<br />

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .<br />

.<br />

<strong>DB</strong>2<br />

.<br />

Man sollte sich angewöhnen, jedes Resultset, jedes Statement und jede Verbindung explizit zu schließen und<br />

sich nicht auf den Garbage-Collector <strong>der</strong> JVM verlassen.<br />

Ein zusammenhängendes Beispiel<br />

Nachfolgend sind die Codebeispiele des letzten Abschnitts nochmal in einem Block zusammengefaßt:<br />

// Import <strong>der</strong> Interfaces des java.sql-Packages import java.sql.*; import java.util.Properties;<br />

public class J<strong>DB</strong>CMain public static void main(String args[]) try // Laden des <strong>DB</strong>2-Treibers Class.forName(kom.ibm.db<strong>2.</strong>jcc.<strong>DB</strong>2Driver“).newInstance();<br />

catch(ClassNotFoundException e) e.printStackTrace(); System.err.println(TTreiber<br />

nicht gefunden!“); System.exit(-1);<br />

try String url = “jdbc:db2://dbserver:1234/Personal“;<br />

// Oeffnen <strong>der</strong> Verbindung zum <strong>DB</strong>MS // Nutzername und Passwort sollten natuerlich // vom Nutzer abgefragt<br />

werden! Connection conn = DriverManager.getConnection(url,“joe“,foo“);<br />

// Erzeugen eines Statements Statement stmt=conn.createStatement();<br />

// Ausfuehren eines Updates String sql = ÜPDATE staff SET salary=3000 WHERE name=’Joe Hacker’“;<br />

stmt.executeUpdate(sql);<br />

// Ausfuehren einer Anfrage sql = SSELECT * FROM staff“; ResultSet result = stmt.executeQuery(sql);<br />

// Auswerten <strong>der</strong> Anfrage-Ergebnisse while( result.next() ) System.out.println( result.getString(name“)+“: “+<br />

Double.toString(result.getDouble(ßalary“))); result.close();<br />

stmt.close();<br />

// Beenden <strong>der</strong> Verbindung conn.close(); catch(Exception e) // Ausgabe <strong>der</strong> Fehlermeldung e.printStackTrace();<br />

System.exit(-1);<br />

Weitergehende Möglichkeiten mit J<strong>DB</strong>C<br />

Die Möglichkeiten von J<strong>DB</strong>C gehen weit über die hier vorgestellten Grundlagen hinaus. Dieser Abschnitt stellt als<br />

Beispiele einige fortgeschrittene Techniken vor: Abfrage <strong>der</strong> Schema-Information, die Bearbeitung von Ergebnismengen<br />

und Transaktionen.


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 67<br />

Nutzung von Metadaten<br />

Bisher wurde vorausgesetzt, daß <strong>der</strong> Programmierer das Schema <strong>der</strong> Datenbank genau kennt. Wenn z.B. <strong>der</strong> Typ eines<br />

Attributs eines Tupels <strong>der</strong> Ergebnismenge unbekannt ist, weiß <strong>der</strong> Entwickler nicht, welche getXXX-Methode<br />

zu benutzen ist.<br />

Diese Schema-Informationen (Metadaten) sind allerdings im Data Dictionary <strong>der</strong> Datenbank gespeichert und<br />

können über J<strong>DB</strong>C abgefragt werden, sofern <strong>der</strong> Treiber und das <strong>DB</strong>MS dies unterstützen. Metadaten stehen an<br />

zwei Stellen zur Verfügung:<br />

• Connection.getMetaData liefert ein DatabaseMetaData - Objekt zurück, das Informationen über<br />

die Datenbank im Allgemeinen enthält, d.h. die Tabellenstruktur, die gespeicherten Prozeduren, den verwendeten<br />

SQL-Dialekt, etc.<br />

• ResultSet.getMetaData liefert ein ResultSetMetaData - Objekt zurück, das Informationen über<br />

die Struktur einer Ergebnismenge enthält, also z.B. Namen und Typen <strong>der</strong> Attribute.<br />

Das folgende Code-Fragment (aufbauend auf <strong>der</strong> oben genutzten Personal-Datenbank) analysiert die Attribut-<br />

Struktur <strong>der</strong> Ergebnismenge einer Anfrage:<br />

/* ... */<br />

// Anfrage ausfuehren ResultSet result = stmt.executeQuery(SSELECT * FROM staff“);<br />

// Metadaten auslesen ResultSetMetaData md = result.getMetaData();<br />

// Ausgabe aller Attributnamen // ACHTUNG: das erste Attribut hat die Position 1 ! for(int idx=1; idx¡=md.getColumnCount()<br />

idx++) System.out.println(md.getColumnName(idx));<br />

/* ... */<br />

Verarbeitung von Ergebnismengen<br />

Ein normales ResultSet-Objekt hat zwei einschränkende Eigenschaften:<br />

• Die Werte können nicht verän<strong>der</strong>t werden.<br />

• Sie besitzen ein sogenanntes forward-only-Cursor 13 , d.h. die Menge kann nur genau einmal vom ersten bis<br />

zum letzten Element durchlaufen werden.<br />

Seit J<strong>DB</strong>C Version <strong>2.</strong>0 existieren scrollbare ResultSets. Mittels diverser Navigationsmethoden kann <strong>der</strong><br />

Zeiger innerhalb <strong>der</strong> Menge beliebig gesetzt werden: auf absolute Positionen, vorwärts o<strong>der</strong> rückwärts.<br />

Außerdem ist es wünschenswert, wenn man die Daten eines ResultSets nachbearbeiten kann. Zu diesem Zweck<br />

existieren än<strong>der</strong>bare ResultSet-Objekte mit updateXXX-Methoden.<br />

Der Typ eines ResultSets wird durch das Statement bestimmt, in dessen Kontext es erzeugt wird. Ein<br />

Statement, das mittels conn.createStatement() erzeugt wurde, generiert stets nicht verän<strong>der</strong>bare und nicht<br />

scrollbare ResultSets. Werden <strong>der</strong> Methode zwei Parameter übergeben, läßt sich dieses Verhalten än<strong>der</strong>n:<br />

Statement stmt = conn.createStatement(int resultSetType, int resultSetConcurrency);<br />

Der Parameter resultSetType kann folgende Werte annehmen:<br />

resultSetType<br />

ResultSet.TYPE FORWARD ONLY<br />

ResultSet.TYPE SCROLL INSENSITIVE<br />

ResultSet.TYPE SCROLL SENSITIVE<br />

Bedeutung<br />

Das ResultSet kann nur einmal vom ersten<br />

bis zum letzten Element durchlaufen<br />

werden.<br />

Das ResultSet ist scrollbar, simultane<br />

Än<strong>der</strong>ungen an<strong>der</strong>er Nutzer bleiben verborgen<br />

Das ResultSet ist scrollbar, Än<strong>der</strong>ungen<br />

an<strong>der</strong>er Nutzer schlagen auf die Werte durch.<br />

13 Cursor steht hier für current set of records.


CAU Kiel, IfI, ISE β SS 2008 <strong>Datenbanken</strong> I <strong>2.</strong> <strong>Relationale</strong> <strong>DB</strong> 68<br />

Für resultSetConcurrency gibt es diese Möglichkeiten:<br />

resultSetConcurrency<br />

ResultSet.CONCUR READ ONLY<br />

ResultSet.CONCUR UPDATABLE<br />

Bedeutung<br />

Das Ergebnis kann nicht verän<strong>der</strong>t werden.<br />

Das Ergebnis kann editiert werden.<br />

Das folgende Code-Fragment erzeugt ein Statement für scrollbare und än<strong>der</strong>bare ResultSets:<br />

/* ... */ Statement stmt = conn.createStatement(ResultSet.TYPE S CROLL I NSENSIT IV E, ResultSet.CONCUR U P D<br />

... ∗ /<br />

// ausfuehren einer Anfrage ResultSet result = stmt.executeQuery(SSELECT * FROM staff“);<br />

// setzt den Zeiger auf Position 2 result.absolute(2);<br />

// setzt den Zeiger auf das erste Tupel result.first();<br />

// aen<strong>der</strong>t das Gehalt result.updateDouble(ßalary“,2000);<br />

Transaktionen<br />

Die J<strong>DB</strong>C-API unterstützt die Nutzung von Transaktionen. Standardmäßig ist definiert, daß jede SQL-Anweisung,<br />

die per executeQuery o<strong>der</strong> executeUpdate ausgeführt wird, einer Transaktion entspricht. Dieses Verhalten<br />

läßt sich über die setAutoCommit-Methode des Connection-Objekts än<strong>der</strong>n. Durch den Parameter false<br />

wird nach Ausführung von executeXXX-Methoden ein expliziter Aufruf von Connection.commit bzw.<br />

Connection.rollback erwartet:<br />

/* ... */<br />

// eine Transaktion fuer sich stmt.executeUpdate( ÜPDATE staff SET salary=3000 WHERE name=’Joe Hacker’“);<br />

conn.setAutoCommit(false);<br />

/**** * Beginn <strong>der</strong> Transaktion ****/<br />

stmt.executeUpdate( ”DELETE FROM staff WHERE name=’Alf Weise’“);<br />

stmt.executeUpdate( ÏNSERT INTO staff (name,salary) VALUES(’Tina Kunterbunt’,1000)“);<br />

// Commit conn.commit();<br />

/**** * Ende <strong>der</strong> Transaktion ****/ /**** * Beginn einer neuen Transaktion ****/<br />

stmt.executeUpdate( ÜPDATE staff SET salary=2000 WHERE name=’Tina Kunterbunt’“);<br />

// Rollback conn.rollback();<br />

/**** * Ende <strong>der</strong> Transaktion ****/<br />

/* ... */<br />

Hinweis: Das zugrunde liegende <strong>DB</strong>MS muß natürlich Transaktionen unterstützen!<br />

Weiterführende Lektüre<br />

Im WWW sind eine Vielzahl von Dokumenten über den Gebrauch von J<strong>DB</strong>C verfügbar, z.B.:<br />

• Java-API Dokumentation:<br />

http://java.sun.com/products/jdk/1.4.2/docs/api/index.html<br />

• J<strong>DB</strong>C-Tutorial von Sun:<br />

http://java.sun.com/docs/books/tutorial/jdbc/<br />

• ein weiteres Sun-Tutorial:<br />

http://developer.java.sun.com/developer/Books/J<strong>DB</strong>CTutorial/<br />

• Kurzübersicht:<br />

http://www.cs.unc.edu/Courses/wwwp-s98/members/thornett/jdbc/<br />

• Code-Beispiele für Java allgemein:<br />

http://www.exampledepot.com/<br />

• ...

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!