Eftersom PRIMARY KEY
fabrikat de inkluderade kolumnerna NOT NULL
automatiskt . Jag citerar manualen här:
Den primära nyckelbegränsningen anger att en kolumn eller kolumner i atable endast kan innehålla unika (icke-duplicerade), icke-nullvärden. Tekniskt sett
PRIMARY KEY
är bara en kombination avUNIQUE
ochNOT NULL
.
Djärv betoning min.
Jag körde ett test för att bekräfta att NOT NULL
är helt redundant i kombination med en PRIMARY KEY
begränsning (i den nuvarande implementeringen, omtestad i version 13). NOT NULL
restriktioner även efter att PK-begränsningen har släppts, oavsett en explicit NOT NULL
klausul vid skapandet.
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<>spela här
Identiskt beteende om NULL
ingår i CREATE TABLE
uttalande.
Det kommer fortfarande inte att skada att behålla NOT NULL
redundant i kodlager om kolumnen ska vara NOT NULL
. Om du senare bestämmer dig för att ändra PK-begränsningen kan du glömma att markera kolumnen NOT NULL
- eller om det ens var tänkt att vara NOT NULL
.
Det finns ett objekt i Postgres TODO-wiki för att koppla bort NOT NULL
från PK-begränsningen. Så detta kan ändras i framtida versioner:
Flytta NOT NULL-begränsningsinformation till pg_constraint
För närvarande lagras NOT NULL-begränsningar i pg_attribute utan någon beteckning på deras ursprung, t.ex. primära nycklar. Ett tydligt problem är att om du släpper en PRIMARY KEY-begränsning inte tar bort NOT NULL-begränsningsbeteckningen. En annan fråga är att vi förmodligen borde tvinga NOT NULL att spridas från överordnade tabeller till barn, precis som CHECK-begränsningar är. (Men påverkar det barn då att tappa PRIMÄRNYCKEL?)
Svar på tillagd fråga
Skulle det inte vara bättre om detta självmotsägande CREATE TABLE bara misslyckades just där?
Som förklarats ovan, detta
foo_id INTEGER NULL PRIMARY KEY
motsvarar (för närvarande) 100 %:
foo_id INTEGER PRIMARY KEY
Sedan NULL
behandlas som brusord i detta sammanhang.
Och vi vill inte att det senare ska misslyckas. Så detta är inte ett alternativ.