Protože PRIMARY KEY
dělá zahrnuté sloupce NOT NULL
automaticky . Zde cituji manuál:
Omezení primárního klíče určuje, že sloupec nebo sloupce tabulky mohou obsahovat pouze jedinečné (neduplicitní), nenulové hodnoty. Technicky
PRIMARY KEY
je pouze kombinacíUNIQUE
aNOT NULL
.
Tučné zdůraznění moje.
Provedl jsem test, abych potvrdil, že NOT NULL
je v kombinaci s PRIMARY KEY
zcela redundantní omezení (v aktuální implementaci, znovu testováno ve verzi 13). NOT NULL
omezení zůstává i po zrušení omezení PK, bez ohledu na explicitní NOT NULL
doložka v době vytvoření.
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<>zde hrajte
Identické chování, pokud NULL
je součástí CREATE TABLE
prohlášení.
Stále nebude na škodu ponechat NOT NULL
redundantně v úložištích kódu, pokud má být sloupec NOT NULL
. Pokud se později rozhodnete změnit omezení PK, možná zapomenete označit sloupec NOT NULL
- nebo zda to dokonce mělo být NOT NULL
.
Ve wiki Postgres TODO je položka k oddělení NOT NULL
z omezení PK. To se tedy může v budoucích verzích změnit:
Přesuňte informace o omezení NOT NULL do pg_constraint
V současné době jsou omezení NOT NULL uložena v pg_attribute bez jakéhokoli označení jejich původu, např. primární klíče. Jedním z zjevných problémů je, že zrušením omezení PRIMARY KEY se neodstraní označení omezení NOT NULL. Dalším problémem je, že bychom pravděpodobně měli vynutit šíření NOT NULL z rodičovských tabulek dětem, stejně jako omezení CHECK. (Ovlivňuje však vypuštění PRIMARY KEY děti?)
Odpověď na přidanou otázku
Nebylo by lepší, kdyby tato protichůdná CREATE TABLE právě tam selhala?
Jak je vysvětleno výše, toto
foo_id INTEGER NULL PRIMARY KEY
je (aktuálně) 100 % ekvivalentní:
foo_id INTEGER PRIMARY KEY
Od NULL
je v tomto kontextu považováno za šumové slovo.
A my bychom nechtěli, aby to druhé selhalo. Takže toto není možnost.