Das MySQL-Kuriositätenkabinett

Zusammengesetzte Fremdschlüssel

Zusammengesetzte Primärschlüssel kommen in der Datenbankwelt allerorten vor, z.B. in Beziehungstabellen. Zusammengesetzte Fremdschlüssel sind seltener, werden aber naturgemäß gebraucht, wenn auf eine Tabelle mit zusammengesetztem Primärschlüssel referenziert werden soll.

Die Syntax für die Erstellung von zusammengesetzten Fremdschlüsseln ist analog zu zusammengesetzten Primärschlüsseln.

Gegeben seien beispielhaft die folgenden Tabellen:

CREATE TABLE `raum` (
 `Buchstabe` char(1) NOT NULL,
 `RaumNr` decimal(3,2) NOT NULL,
 PRIMARY KEY (`Buchstabe`,`RaumNr`)
);

CREATE TABLE `findetstatt` (
 `Nr` int(11) DEFAULT NULL,
 `Belegnr` int(11) DEFAULT NULL,
 `Abk` varchar(5) DEFAULT NULL,
 `RaumNr` decimal(3,2) DEFAULT NULL,
 `Buchstabe` char(1) DEFAULT NULL
);

Ein zusammengesetzter Fremdschlüssel, der von von „findetstatt“ auf „raum“ verweist, wird nun erstellt mit:

alter table findetstatt add foreign key(buchstabe, raumnr) references raum(buchstabe,raumnr);

Falle: Error 1215

Zu beachten ist, dass die Reihenfolge, in der die Spalten des Fremdschlüssels angegeben werden, der Reihenfolge entsprechen muss wie sie in der Definition des Primärschlüssels, auf den sich der Fremdschlüssel bezieht, angegeben ist. Wird dies nicht beachtet, quittiert MySQL das mit einer nichtssagenden Fehlermeldung.

mysql> alter table findetstatt add foreign key(raumnr,buchstabe) references raum(raumnr,buchstabe);
ERROR 1215 (HY000): Cannot add foreign key constraint

Das gleiche passiert, wenn man auf die Idee kommt, nur die Spalte „RaumNr“ mit einem Fremdschlüssel-Constraint zu belegen, da sich dieser dann auf den zweiten Teil des Primärschlüssels in der Tabelle „raum“ bezieht:

mysql> alter table findetstatt add foreign key(raumnr) references raum(raumnr);
ERROR 1215 (HY000): Cannot add foreign key constraint

Wird nur der erste Teil eines mehrteiligen Primärschlüssels referenziert, ist das problemlos möglich, z.B.:

alter table findetstatt add foreign key(buchstabe) references raum(buchstabe);