Exkurs - Datenbank-View
Die freund
-Tabelle speichert eigentlich nur eine Richtung der Freund-Beziehung, wenn man PNR1
als Start- und PNR2 als Zielpunkt der Beziehung ansieht:
Will man darauf Abfragen stellen, wird dies schnell kompliziert. Als Beispiel sollen alle Datensätze gefunden werden, die zum Benutzer Paul Winkelmann gehören:
SELECT freund.*
FROM benutzer, freund
WHERE benutzer.Name = 'Winkelmann' AND benutzer.Vorname = 'Paul'
AND ( benutzer.PNR = freund.PNR1 OR benutzer.PNR = freund.PNR2 )
Der Grund für den aufwändigen WHERE
-Teil liegt darin, dass die Personennummer von Herr
Winkelmann ja in PNR1
oder in PNR2
auftauchen kann.
Als Abhilfe bietet sich eine Tabelle an, die beide Richtungen speichert. Dabei können aber leicht Inkonsistenzen auftreten, wie das folgende Beispiel zeigt (erkennst du das Problem?).
Klicke, um den Fehler zu zeigen.
Eine weitere Tabelle?
Eine Lösung wäre eine weitere Tabelle, die genau die "Gegenseite" der freund-Beziehung darstellt. Ein einfacher SQL-Befehl erzeugt eine solche Tabelle:
SELECT PNR2 AS PNR1, PNR1 AS PNR2
FROM freund
... und ein neuer SQL-Befehl vereinigt die Ursprungstabell mit der neuen Tabelle:
SELECT PNR1, PNR2
FROM freund
UNION
SELECT PNR2 AS PNR1, PNR1 AS PNR2
FROM freund
Mit dem Schlüsselwort UNION lassen sich die Ergebnisse zweier gleichartiger SQL-Befehle vereinigen. Wichtig ist, dass beide SQL-Befehle die gleichen Spalten auswählen (Anzahl, Datentyp).
Datenbank-View zur Vereinfachung
Es wäre schön, wenn man die oben erzeugte Tabelle immer zur Verfügung hätte - am Besten, ohne die Daten wirklich doppelt zu speichern. Zu diesem Zweck gibt es sog. Sichten (engl.: Views) auf die Datenbank.
Datenbank-Views speichern SELECT
-Befehle unter einem Namen ab. Unter diesem Namen
kann in weiteren SQL-Befehlen auf die Ergebnis-Tabelle des SELECT
zugegriffen werden, als ob es sich um eine
reale Tabelle handelt. In der Regel können Daten in Views aber nicht eingefügt oder geändert werden.
Einen Datenbankview freund2
erzeugt der folgende SQL-Befehl:
CREATE VIEW freund2 AS
SELECT PNR1, PNR2
FROM freund
UNION
SELECT PNR2 AS PNR1, PNR1 AS PNR2
FROM freund
Die gbuch-Datenbank enthält diesen View schon, so dass du jetzt auf den View freund2
wie auf
eine Tabelle zugreifen kannst. Die Anfangsaufgabe (alle Datensätze von Herrn Winkelmann) lässt sich jetzt viel einfacher
lösen:
SELECT freund2.*
FROM benutzer, freund2
WHERE benutzer.Name = 'Winkelmann' AND benutzer.Vorname = 'Paul'
AND benutzer.PNR = freund2.PNR1