Im Bsp. auf Seite 131 Buch Datenbanksysteme (Kemper) werden 2
Möglichkeiten beschrieben.
Bei b.) wird der Obertyp als Sicht modelliert, dabei ensteht jedoch das
Problem, dass für 3 unterschiedliche Personen in der Tabelle Professor,
Assistent oder AndererAngestellter die gleiche PersNr vorhanden sein kann.
Eine Überprüfung mit einer subquery in einem constraint ist - soweit ich
weiß - in Oracle nicht möglich.
Wie wird diese Generalisierung nun richtig modelliert? Füge ich die
Attriubte des Oberttyps in den Untertyp mit FOREIGN KEY Definitionen ein
- um eine Bevorzugung des Untertypen zu erreichen - oder modelliere ich
den Untertypen als Sicht so wie im Buch bei Bsp. a.)? Im ersten Fall
(FOREIGN KEYs) habe ich die Nachteile, dass ich Werte doppelt erfassen
muß bzw. wird dadurch auch mehr Speicherplatz benötigt oder werden
Datenbankintern nur die Verweise gespeichert?
Mit netten Grüßen
Christoph Winklhofer
Das Relationenschema sieht dann wie folgt aus:
{Forenbenutzer: ID:integer, Name:string} [ID ist Primärschlüssel]
{Benutzer: ID:integer} [ID ist Primär- und Fremdschlüssel]
{Moderator: ID:integer} [ID ist Primär- und Fremdschlüssel]
{Administrator: ID:integer} [ID ist Primär- und Fremdschlüssel]
Es ist bei der Relation Benutzer nur notwenig, zu speichern, wer
Benutzer ist. Der Name steht ohnehin in der Relation Forenbenutzer.
Entsprechend erfolgt das Erstellen der Tabellen in SQL:
CREATE TABLE Forenbenutzer (
ID INTEGER NOT NULL,
Name VARCHAR(100) NOT NULL,
PRIMARY KEY (ID)
);
CREATE TABLE Benutzer (
ID INTEGER NOT NULL,
PRIMARY KEY (ID),
FOREIGN KEY (ID) REFERENCES Forenbenutzer (ID)
);
CREATE TABLE Moderator (
ID INTEGER NOT NULL,
PRIMARY KEY (ID),
FOREIGN KEY (ID) REFERENCES Forenbenutzer (ID)
);
CREATE TABLE Gast (
ID INTEGER NOT NULL,
PRIMARY KEY (ID),
FOREIGN KEY (ID) REFERENCES Forenbenutzer (ID)
);
Möchtest du nun einen "normalen" Benutzer in die Datenbank eintragen, so
musst du ihn zunächst in die Relation Forenbenutzer eintragen, bevor du
ihn in die Relation Benutzer einträgst. Jede andere Vorgehensweise führt
zu einer Verletzung der FOREIGN KEY-Constraints und ist somit unzulässig
und wird vom DBMS entsprechend abgelehnt.
In dem Fall, dass man ID und Namen aller Forenbenutzer abfragen möchte,
so reicht dieses (triviale) SQL-Statement:
SELECT * FROM Forenbenutzer;
Möchte man allerdings nur ID und Namen aller "normalen" Benutzer haben,
so braucht man einen NATURAL JOIN zwischen Forenbenutzer und Benutzer:
SELECT * FROM Forenbenutzer f, Benutzer b WHERE f.ID=b.ID;
Und das kannst du natürlich auch als View speichern:
CREATE VIEW Benutzerliste AS
SELECT f.ID, f.Name FROM Forenbenutzer f, Benutzer b WHERE f.ID=b.ID;
Habe jetzt nicht im Kemper nachgesehen, wie Generalisierungen dort
beschrieben werden, hoffe allerdings, mit dieser Beschreibung
weiterhelfen zu können.
MfG
Paulchen Panther