Virtabs: "Schreibbare Views?"

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.

 

[Virtabs] [Positionierung] [Schreibbare Views?] [Schreibbare Views!] [Feature-Überblick] [Virtabs entwickeln] [Unterstützte Datenbanken] [Referenz] [Konzepte] [Application-Interfaces] [Struktur der Demo-DB] [Guided tour] [Beispiel-Code]