Grundkurs SQL

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 oder NO 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.