Fordi PRIMARY KEY
gør de inkluderede kolonne(r) NOT NULL
automatisk . Jeg citerer manualen her:
Den primære nøglebegrænsning specificerer, at en kolonne eller kolonner af atable kun kan indeholde unikke (ikke-duplikerede), ikke-null-værdier. Teknisk set PRIMARY KEY
er blot en kombination af UNIQUE
og NOT NULL
.
Fed fremhævelse mine.
Jeg kørte en test for at bekræfte, at NOT NULL
er fuldstændig redundant i kombination med en PRIMARY KEY
begrænsning (i den nuværende implementering, gentestet i version 13). NOT NULL
begrænsning forbliver selv efter at have droppet PK-begrænsningen, uanset en eksplicit NOT NULL
klausul på oprettelsestidspunktet.
CREATE TABLE foo (foo_id int PRIMARY KEY);
ALTER TABLE foo DROP CONSTRAINT foo_pkey;
db=# \d foo
table »public.foo«
column | type | attribute
--------+---------+-----------
foo_id | integer | not null -- stays
db<>spil her
Identisk adfærd hvis NULL
er inkluderet i CREATE TABLE
erklæring.
Det vil stadig ikke skade at beholde NOT NULL
redundant i kodelagre, hvis kolonnen formodes at være NOT NULL
. Hvis du senere beslutter dig for at ændre PK-begrænsningen, glemmer du muligvis at markere kolonnen NOT NULL
- eller om det overhovedet skulle være NOT NULL
.
Der er et element i Postgres TODO wiki, der skal afkoble NOT NULL
fra PK-begrænsningen. Så dette kan ændre sig i fremtidige versioner:
Flyt NOT NULL-begrænsningsoplysninger til pg_constraint
I øjeblikket er NOT NULL-begrænsninger gemt i pg_attribute uden nogen betegnelse for deres oprindelse, f.eks. primære nøgler. Et tydeligt problem er, at droppe en PRIMARY KEY-begrænsning ikke fjerner NOT NULL-betingelsen. Et andet problem er, at vi sandsynligvis skal tvinge NOT NULL til at blive udbredt fra overordnede tabeller til børn, ligesom CHECK-begrænsninger er. (Men så påvirker det børn at droppe PRIMÆR NØGLE?)
Svar på tilføjet spørgsmål
Ville det ikke være bedre, hvis dette selvmodsigende CREATE TABLE bare mislykkedes lige dér?
Som forklaret ovenfor er dette
foo_id INTEGER NULL PRIMARY KEY
svarer (i øjeblikket) 100 % til:
foo_id INTEGER PRIMARY KEY
Siden NULL
behandles som støjord i denne sammenhæng.
Og vi ønsker ikke, at sidstnævnte fejler. Så dette er ikke en mulighed.