Die Aufgabenstellung:
In einer normalisierten relationalen SQL-Datenbank ist die
für eine bestimmte Aufgabe erforderliche Information in der
Regel über mehrere Tabellen verteilt, die mittels
1:n-Beziehungen (primary key - foreign key; Primärschlüssel -
Fremdschlüssel) miteinander verknüpft sind. Um solche
tabellenübergreifend miteinander verknüpft vorliegenden
Informationen abzufragen, existiert das Konzept der View:
Eine View erscheint als Tabelle, deren Zeilen Spalten aus
verschiedenen Tabellen enthalten, die über Schlüsselfelder
miteinander verknüpft sind.
Eine View verhält sich allerdings nur bei Abfragen ('select'-statements) wie eine Tabelle: Weder
kann mit 'insert' ein neuer Datensatz angehängt werden, noch können Spalteneinträge gelöscht
('delete') oder geändert ('update') werden. Somit ist eine View ein reines Abfrageinstrument.
Ein Beispiel:
Gegeben seien folgende Tabellen der DEMO-Datenbank zur Erfassung von Geschäftsstellen
(LOCATION) und diesen zugeordneten Abteilungen (DEPARTMENT) mit ihren Adressen
(ADDRESS):
Tabelle LOCATION:
|
Spalte
|
Datentyp
|
Erläuterung
|
location_id
|
number(3)
|
primary key
|
regional_group
|
varchar2(20)
|
eindeutiger Name (Zweitschlüssel)
|
Tabelle ADDRESS:
|
Spalte
|
Datentyp
|
Erläuterung
|
address_id
|
number(6)
|
primary key
|
street
|
varchar2(40)
|
|
city
|
varchar2(30)
|
|
state
|
varchar2(2)
|
|
zip_code
|
varchar2(9)
|
|
Tabelle DEPARTMENT:
|
Spalte
|
Datentyp
|
Erläuterung
|
department_id
|
Number(2)
|
primary key
|
name
|
varchar2(14)
|
in einer Geschäftsstelle eindeutiger Name einer
Abteilung (Teil des zusammengesetzten Zweitschlüssels)
|
location_id
|
number(3)
|
foreign key, references location(location_id)
(Teil des zusammengesetzten Zweitschlüssels)
|
address_id
|
number(6)
|
foreign key, references address(address_id)
|
Zwischen diesen drei Tabellen existieren somit zwei Master-Detail-Beziehungen:
LOCATION1:n DEPARTMENT:
LOCATION ist Master-Tabelle, DEPARTMENT die Detail-Tabelle, denn eine
Geschäftsstelle (= regional group) beheimatet mehrere Abteilungen.
ADDRESS1:n DEPARTMENT:
ADDRESS ist Master-Tabelle, DEPARTMENT die Detail-Tabelle, denn mehrere
Departments können dieselbe Adresse haben. Adressen gibt es aber auch von Kunden
(customer).
Sonderbedingung: Da es in ADDRESS keinen Zweitschlüssel gibt, kann ein Eintrag ADDRESS
nur über eine zugeordnete Detailtabelle identifiziert werden.
Eine tabellenübergreifende View sei folgendermaßen definiert:
CREATE VIEW v_depts AS
SELECT regional_group, name, address_id, street, city, state, zip_code
FROM location, department, address
WHERE location.location_id = department.location_id
AND department.address_id = address.address_id;
Die Tabellen sollen folgende Dateninhalte haben:
Tabelle LOCATION:
|
location_id
|
regional_group
|
122
|
New York
|
123
|
Chicago
|
Tabelle ADDRESS:
|
address_id
|
street
|
city
|
state
|
zip_code
|
2
|
4 E 15th st
|
New York
|
NY
|
10003
|
3
|
12 N 103rd Ave
|
New York
|
NY
|
10005
|
8
|
5017 Michigan Drv
|
Chicago
|
IL
|
15002
|
9
|
5017 Michigan Drv
|
Chicago
|
IL
|
15002
|
Tabelle DEPARTMENT:
|
department_id
|
name
|
location_id
|
address_id
|
12
|
research
|
122
|
2
|
13
|
sales
|
122
|
3
|
30
|
sales
|
123
|
8
|
34
|
operations
|
123
|
9
|
Die View liefert dann folgende Datensätze:
select * from v_depts:
|
regional_group
|
name
|
street
|
city
|
state
|
zip_code
|
New York
|
research
|
4 E 15th st
|
New York
|
NY
|
10003
|
New York
|
sales
|
12 N 103rd Ave
|
New York
|
NY
|
10005
|
Chicago
|
sales
|
5017 Michigan Drv
|
Chicago
|
IL
|
15002
|
Chicago
|
operations
|
5017 Michigan Drv
|
Chicago
|
IL
|
15002
|
Das Problem:
Eine unmögliche Operation (ORA-01779) auf Basis der vorliegenden View-Definition bildet z
.B. folgende Einfügeoperation, mit der die Abteilung 'research' der Geschäftsstelle 'Dallas' neu
erzeugt werden soll.
insert into v_depts (regional_group,name,street,city,state,zip_code)
VALUES ('Dallas','research','3 Walnut Ave','Dallas','TX','25712') ;
In der klassischen (Attribute mehrerer Tabellen umfassenden) View ist die Bedeutung
(Semantik) dieser Operation undefiniert: Es ist zunächst unklar, welche Werte für location_id,
department_id und address_id neu vergeben werden sollen (denn sie dürfen aufgrund ihrer
Primärschlüsselfunktion nicht leer bleiben), und ob die Nichtexistenz der Geschäftsstelle 'Dallas'
bzw. deren Adresse einen Fehler darstellt, bzw. ob eine neuer Eintrag in LOCATION und/oder
ADDRESS erzeugt werden soll.
Dennoch ist intuitiv klar, was gewollt ist:
-
Existiert noch kein Eintrag in LOCATION mit regional_group = 'Dallas', muss dieser mit
neu erzeugter location_id neu angelegt werden, ansonsten muss die location_id des
vorhandenen Eintrags gefunden werden. Der Wert für location_id und address_id muss
aus einer internen Sequenz (Nummerngenerator) gewonnen werden.
-
Die location_id des Eintrags 'Dallas' in LOCATION sowie address_id in ADDRESS
bilden die Fremdschlüssel in DEPARTMENT, und müssen natürlich in den neuen Eintrag
in DEPARTMENT übernommen werden.
-
Existiert noch kein Eintrag in DEPARTMENT mit name = 'research' und location_id =
'124', muss dieser mit neu erzeugter department_id angelegt werden. Dann muss auch ein
neuer Adressdatensatz (nicht notwendigerweise eine tatsächlich neue Adresse!) angelegt
werden.
-
Die eingefügte Zeile soll bei der Abfrage genauso wieder erscheinen (Schreib/Lese
-Konsistenz).
Analog verhält es sich mit
UPDATE v_depts WHERE regional_group = 'New York' SET regional_group = 'New York
City';
oder mit einer 'DELETE'-Anweisung. In jedem Fall ist die Semantik der klassischen View
undefiniert, während sich intuitiv Algorithmen zur Neuerzeugung, Löschung und Verknüpfung
von Tabelleneinträgen angeben lassen.
|