Advanced MySQL - Referentielle Integrität - Fremdschlüssel - Feinheiten
1. Auswirkungen
Und was bewirkt nun dieser Fremdschlüssel? Nun, man kann da an ein paar Schrauben drehen, aber dazu äußere ich mich im nächsten Abschnitt. Konzentrieren wir uns zunächst auf die Standardeinstellungen. Folgende Dinge funktionieren also nicht mehr.
-
Man kann in der Tabelle
parent
keinen Datensatz mehr löschen, wenn es einen entsprechenden Fremdschlüssel in der Tabellechild
gibt. -
Man kann der Tabelle
child
keinen Datensatz einfügen oder ändern, wenn der angegebene Wert des Fremdschlüssels nicht inparent
vorhanden ist. -
Hat man die Spalte für den Fremdschlüssel als
NOT NULL
festgelegt, so muss der Wert des Fremdschlüssels inparent
vorhanden sein. Ohne diese Anweisung lässt sich ein Datensatz einfügen oder ändern, wenn man beim Fremdschlüssel nichts angibt.
2. Bedingungen
Damit das mit dem FOREIGN KEY
funktioniert, muss man auf ein paar Dinge achten, die ich euch jetzt zu Gehör bringen werde.
Tabellentypen
Beide(!) Tabellen müssen vom Typ InnoDb sein. Eine Kombination mit einer MyISAM funktioniert nicht. Ach ja, temporäre Tabellen sind auch ein no-go, aber zu denen äußere ich mich derzeit noch nicht. Kommt später.
Das Feld in der Elterntabelle
... muss auf jeden Fall einen Index haben. Also einen PRIMARY KEY
, einen UNIQUE KEY
oder einen
INDEX/KEY
. FULLTEXT
dagegen geht nicht. Warum? Nun, mal abgesehen von der Idiotie einer solchen Vorgehensweise
gibt es immer noch die unterschiedlichen Tabellentypen. Also denkt mal scharf nach.
Spaltentyp
Wegen einer Längenbegrenzung bei Fremdschlüsseln darf die entsprechende Spalte in der Elterntabelle nicht vom Typ BLOB
oder
TEXT
sein. Mal ganz abgesehen von der Sinnhaftigkeit. VARCHAR
dagegen ist erlaubt, auch wenn ich davon nicht
so viel halte.
CREATE TABLE parent
(
id varchar(255),
key (id)
) ENGINE=INNODB;
CREATE TABLE child
(
id INT,
parent_id varchar(255),
FOREIGN KEY (parent_id) REFERENCES parent(id)
) ENGINE=INNODB;
3. CONSTRAINT
Das ist zunächst mal nur eine pisselige Bedingung, auch als Zwang bezeichnet. Damit können zusätzliche Überprüfungen vorgenommen werden.
Leider unterstützt MySQL hier nur die Fremdschlüssel. Eine "inhaltliche" Validierung zum Beispiel über CHECK
ist nicht
möglich.
Ein Hinweis
In der Doku von MySQL findet sich zwar ein Hinweis auf CONSTRAINT
, aber das ist wohl nur ein Hinweis, der wegen der
Kompatibilität zu anderen Datenbanksystemen aufgeführt wurde. Wer sich also mit Oracle oder dem MS SQL-Server auskennt, dem sei das gesagt.
Ein FOREIGN KEY
von MySQL entspricht einem CONSTRAINT FOREIGN KEY
.
zurück zum vorherigen Abschnitt weiter zum nächsten Abschnitt