Datenbanken I 2. Relationale DB - Technologie der ...
Datenbanken I 2. Relationale DB - Technologie der ...
Datenbanken I 2. Relationale DB - Technologie der ...
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 />
• ...