Wenn man sich mit Datenbanken beschäftigt, dann hat man immer wieder mit Fremdschlüssel zu tun. Ich bin ein großer Fan von Fremdschlüsseln: Wenn sie sprechend benannt wurden, dann kann man mit ihnen fremde Datenbanken gleich besser verstehen. Besonders weil ich dann gerne Datenbank-Diagramme mit dem Management Studio erstellen lasse… 😉

Der eigentliche Zweck ist aber natürlich praktischer: Es werden nur solche Werte zugelassen, die in der primäre Tabelle auch tatsächlich existieren, z.B. ein Mitarbeiter kann nur in einer Abteilung sein, die es auch wirklich gibt. Neben den Problemen mit historischen Daten, die sehr sauber modelliert werden müssen, gibt es ein Feature, das weitgehend unbekannt ist:

Wenn man NULL-Werte zulässt, dann ist NULL in den Fremdschlüsselwerten grundsätzlich erlaubt. Das ist bei einsegmentigen Schlüssel total einsichtig, bei zusammengesetzen führt es in der Regel zu Verblüffung. Ich mache mal ein Beispiel:

Ich habe eine Tabelle "primtab" mit dem Schlüssel bestehend aus pk1 und pk2. Und die Tabelle "reftab", die auf die Tabelle "primtab" verweist. Mit beiliegenden Code kann man ein Beispiel mit Daten anlegen.

create table primtab (
pk1 integer not null,
pk2 integer not null,
primary key(pk1, pk2),
misc integer
– …
)

create table reftab (
pk integer not null primary key,
fk1 integer null,
fk2 integer null,
foreign key (fk1, fk2) references primtab(pk1, pk2),
misc integer
– …
)

insert into primtab (pk1, pk2, misc) values (1,1,1)
insert into primtab (pk1, pk2, misc) values (1,2,1)
insert into primtab (pk1, pk2, misc) values (1,3,1)
insert into primtab (pk1, pk2, misc) values (2,1,1)
insert into primtab (pk1, pk2, misc) values (2,2,1)

insert into reftab (pk, fk1, fk2, misc) values (1,1,1,1)
insert into reftab (pk, fk1, fk2, misc) values (2,1,2,1)
insert into reftab (pk, fk1, fk2, misc) values (3,1,3,1)
insert into reftab (pk, fk1, fk2, misc) values (4,1,1,1)
insert into reftab (pk, fk1, fk2, misc) values (5,2,1,1)
insert into reftab (pk, fk1, fk2, misc) values (6,2,2,1)
insert into reftab (pk, fk1, fk2, misc) values (7,1,1,1)
insert into reftab (pk, fk1, fk2, misc) values (8,2,1,1)

Da für die Fremdschlüsselfelder fk1 und fk2 NULL erlaubt ist, kann man den Wert auch für Beide setzen.

Update reftab
set fk1=NULL,
fk2=NULL
where pk=1

Man kann aber auch nur einen der Werte auf NULL setzen:

Update reftab
set fk2=NULL
where fk2=1

oder

Update reftab
set fk1=NULL
where fk1=1

Für mich war das damals völlig unerwartet und erst nach endlosen Diskussionen in Newsgroups konnte ich mich damit abfinden…