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
parentkeinen Datensatz mehr löschen, wenn es einen entsprechenden Fremdschlüssel in der Tabellechildgibt. -
Man kann der Tabelle
childkeinen Datensatz einfügen oder ändern, wenn der angegebene Wert des Fremdschlüssels nicht inparentvorhanden ist. -
Hat man die Spalte für den Fremdschlüssel als
NOT NULLfestgelegt, so muss der Wert des Fremdschlüssels inparentvorhanden 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