7.3.3 Tabellen gegen Integritätsverlust schützen
Die Abbildung zeigt Beispieleinträge für die eben erstellten Datenbanktabellen. Würde jetzt eine Postleitzahl in der Tabelle ort auf Grund einer falschen Eintragung geändert werden, so gäbe es in der Tabelle mitarbeiter plötzlich einen Eintrag für den es keine Entsprechung mehr in der Tabelle ort gibt - es wäre nun nicht mehr zu ermitteln, wo der Mitarbeiter wohnt!
Genau dies zu verhindern ist der Sinn der referentiellen Integrität.
Wird diese durch das DBMS überwacht so ist das Ändern oder Löschen eines Datensatzes nicht möglich
solange der Wert eines Fremdschlüssels noch auf diesen Datensatz verweist.
So umgeht man das Problem, dass ein Eintrag ins Leere verläuft.
Da solche Änderungen dennoch in
bestimmten Situationen (etwa bei fehlerhaften Einträgen) vorkommen können, kann man in
der SQL-Anweisung bei der Festlegung eines Fremdschlüssels definieren, wie mit solch einem Problem zu verfahren ist.
Mit ON DELETE ...
ON UPDATE ...
kann festgelegt werden, was beim Löschen oder beim Ändern geschehen soll:
RESTRICT
oderNO ACTION
SET NULL
SET DEFAULT
(gehört zum SQL-Standard, ist mit MySQL nicht umsetzbar)CASCADE
RESTRICT
verhindert das Ändern und Löschen eines
Datensatzes in den Tabellen, auf den sich ein Fremdschlüssel bezieht und
würde ein Ändern und Löschen zurückweisen. Es entspricht der
Standardeinstellung.
Sobald kein Bezug mehr zur Elterntabelle hergestellt ist, legt
SET NULL
fest, dass der Fremdschlüssel auf NULL
gesetzt wird. (Die betroffene Spalte darf nicht als
NOT NULL
definiert sein!)
Das Schlüsselwort SET DEFAULT
entspricht dem SET NULL
mit dem Unterschied, dass ein vorher definierter Wert standardmäßig für
den Fremdschlüssel verwendet wird.
Schließlich bewirkt CASCADE
eine automatische
Fremdschlüsseländerung sobald der Primärschlüssel geändert
bzw. gelöscht wird.
Es stellt sich nun die Frage wie man über SQL dem Datenbanksystem mitteilt, welche Aktion bei einer Verletzung der referentiellen Integrität angewandt werden soll. Diese Aktion gehört zur Definition des Fremdschlüssels und folgt dieser direkt.
Nun sollen zwei Dinge am bisher bestehenden Beispiel umgesetzt werden. Zum einen
soll die Postleitzahl auf NULL
gesetzt werden, sobald der entsprechende Satz
in der Tabelle ort gelöscht wird.
Und zum anderen soll die Postleitzahl automatisch aktualisiert werden, wenn diese in der
Tabelle ort geändert wird. Die SQL-Anweisungen hierfür sehen
folgendermaßen aus:
[diese kann Anweisung getestet werden]
CREATE TABLE mitarbeiter
(
personal_ID CHAR(4) NOT NULL,
name VARCHAR(30) NOT NULL,
strasse VARCHAR(50) NOT NULL,
plz VARCHAR(5) NULL DEFAULT '00000',
geburtsdatum DATE NULL DEFAULT '0000-00-00',
CONSTRAINT primaryKey_mitarbeiter PRIMARY KEY (personal_ID),
CONSTRAINT foreignKey_mitarbeiter FOREIGN KEY (plz)
REFERENCES ort(plz)
ON DELETE SET NULL
ON UPDATE CASCADE
) ENGINE=INNODB
Bei der Notation dieser Anweisungen erscheint zuerst das Ereignis
(ON DELETE
oder ON UPDATE
)
und dann die Aktion (bspw. SET NULL
), die bei Auftreten des entsprechenden
Ereignisses ausgeführt werden soll.