{"id":642,"date":"2007-08-11T12:09:33","date_gmt":"2007-08-11T10:09:33","guid":{"rendered":"http:\/\/www.glorf.it\/blog\/2007\/08\/11\/sql-talk\/fremdschluessel-falle"},"modified":"2007-08-11T12:13:47","modified_gmt":"2007-08-11T10:13:47","slug":"fremdschluessel-falle","status":"publish","type":"post","link":"http:\/\/www.glorf.it\/blog\/2007\/08\/11\/sql-talk\/fremdschluessel-falle","title":{"rendered":"Fremdschl&#252;ssel-Falle"},"content":{"rendered":"<p>Wenn man sich mit Datenbanken besch&#228;ftigt, dann hat man immer wieder mit Fremdschl&#252;ssel zu tun. Ich bin ein gro&#223;er Fan von Fremdschl&#252;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&#8230; \ud83d\ude09<\/p>\n<p>Der eigentliche Zweck ist aber nat&#252;rlich praktischer: Es werden nur solche Werte zugelassen, die in der prim&#228;re Tabelle auch tats&#228;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&#252;ssen, gibt es ein Feature, das weitgehend unbekannt ist:<\/p>\n<p>Wenn man NULL-Werte zul&#228;sst, dann ist NULL in den Fremdschl&#252;sselwerten grunds&#228;tzlich erlaubt. Das ist bei einsegmentigen Schl&#252;ssel total einsichtig, bei zusammengesetzen f&#252;hrt es in der Regel zu Verbl&#252;ffung. Ich mache mal ein Beispiel: <\/p>\n<p>Ich habe eine Tabelle &quot;primtab&quot; mit dem Schl&#252;ssel bestehend aus pk1 und pk2. Und die Tabelle &quot;reftab&quot;, die auf die Tabelle &quot;primtab&quot; verweist. Mit beiliegenden Code kann man ein Beispiel mit Daten anlegen.<\/p>\n<p><code lang=\"sql\">create table primtab (<br \/>\npk1 integer not null,<br \/>\npk2 integer not null,<br \/>\n\tprimary key(pk1, pk2),<br \/>\nmisc\tinteger<br \/>\n&#8211; &#8230;<br \/>\n)<\/p>\n<p>create table reftab (<br \/>\npk\tinteger not null primary key,<br \/>\nfk1 integer null,<br \/>\nfk2 integer null,<br \/>\n\tforeign key (fk1, fk2) references primtab(pk1, pk2),<br \/>\nmisc integer<br \/>\n&#8211; &#8230;<br \/>\n)<\/p>\n<p>insert into primtab (pk1, pk2, misc) values (1,1,1)<br \/>\ninsert into primtab (pk1, pk2, misc) values (1,2,1)<br \/>\ninsert into primtab (pk1, pk2, misc) values (1,3,1)<br \/>\ninsert into primtab (pk1, pk2, misc) values (2,1,1)<br \/>\ninsert into primtab (pk1, pk2, misc) values (2,2,1)<\/p>\n<p>insert into reftab (pk, fk1, fk2, misc) values (1,1,1,1)<br \/>\ninsert into reftab (pk, fk1, fk2, misc) values (2,1,2,1)<br \/>\ninsert into reftab (pk, fk1, fk2, misc) values (3,1,3,1)<br \/>\ninsert into reftab (pk, fk1, fk2, misc) values (4,1,1,1)<br \/>\ninsert into reftab (pk, fk1, fk2, misc) values (5,2,1,1)<br \/>\ninsert into reftab (pk, fk1, fk2, misc) values (6,2,2,1)<br \/>\ninsert into reftab (pk, fk1, fk2, misc) values (7,1,1,1)<br \/>\ninsert into reftab (pk, fk1, fk2, misc) values (8,2,1,1)<\/code><\/p>\n<p>Da f&#252;r die Fremdschl&#252;sselfelder fk1 und fk2 NULL erlaubt ist, kann man den Wert auch f&#252;r Beide setzen. <\/p>\n<p><code lang=\"sql\">Update reftab<br \/>\n\tset fk1=NULL,<br \/>\n\t\tfk2=NULL<br \/>\nwhere  pk=1<\/code><\/p>\n<p>Man kann aber auch nur einen der Werte auf NULL setzen:<\/p>\n<p><code lang=\"sql\">Update reftab<br \/>\n\tset fk2=NULL<br \/>\nwhere  fk2=1<br \/>\n<\/code><\/p>\n<p>oder <\/p>\n<p><code lang=\"sql\">Update reftab<br \/>\n\tset fk1=NULL<br \/>\nwhere fk1=1<br \/>\n<\/code><\/p>\n<p>F&#252;r mich war das damals v&#246;llig unerwartet und erst nach endlosen Diskussionen in Newsgroups konnte ich mich damit abfinden&#8230;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Wenn man sich mit Datenbanken besch&#228;ftigt, dann hat man immer wieder mit Fremdschl&#252;ssel zu tun. Ich bin ein gro&#223;er Fan von Fremdschl&#252;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&#8230; \ud83d\ude09 Der eigentliche Zweck ist aber [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[3],"tags":[],"_links":{"self":[{"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/posts\/642"}],"collection":[{"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/comments?post=642"}],"version-history":[{"count":0,"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/posts\/642\/revisions"}],"wp:attachment":[{"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/media?parent=642"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/categories?post=642"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/tags?post=642"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}