Da der PRIMARY KEY
macht die eingeschlossene(n) Spalte(n) NOT NULL
automatisch . Ich zitiere das Handbuch hier:
Die Primärschlüsseleinschränkung gibt an, dass eine oder mehrere Spalten einer Tabelle nur eindeutige (nicht duplizierte) Nicht-Null-Werte enthalten dürfen. Technisch gesehen PRIMARY KEY
ist lediglich eine Kombination aus UNIQUE
und NOT NULL
.
Fettdruck von mir.
Ich habe einen Test durchgeführt, um zu bestätigen, dass NOT NULL
ist in Kombination mit einem PRIMARY KEY
völlig redundant Constraint (in der aktuellen Implementierung, erneut getestet in Version 13). Der NOT NULL
Einschränkung bleibt auch nach dem Löschen der PK-Einschränkung, unabhängig von einem expliziten NOT NULL
-Klausel zum Zeitpunkt der Erstellung.
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<>hier fummeln
Identisches Verhalten bei NULL
ist in CREATE TABLE
enthalten Aussage.
Es schadet trotzdem nicht, NOT NULL
beizubehalten redundant in Code-Repositories, wenn die Spalte NOT NULL
sein soll . Wenn Sie sich später entscheiden, die PK-Einschränkung zu ändern, vergessen Sie möglicherweise, die Spalte NOT NULL
zu markieren - oder ob es überhaupt NOT NULL
sein sollte .
Es gibt ein Element im Postgres TODO-Wiki, um NOT NULL
zu entkoppeln aus der PK-Einschränkung. Dies könnte sich also in zukünftigen Versionen ändern:
Verschiebt NOT NULL Constraint-Informationen nach pg_constraint
Derzeit werden NOT NULL-Einschränkungen in pg_attribute ohne Angabe ihrer Herkunft gespeichert, z. Primärschlüssel. Ein offensichtliches Problem besteht darin, dass das Löschen einer PRIMARY KEY-Einschränkung die NOT NULL-Einschränkungsbezeichnung nicht entfernt. Ein weiteres Problem ist, dass wir wahrscheinlich erzwingen sollten, dass NOT NULL von übergeordneten Tabellen an untergeordnete Tabellen weitergegeben wird, genau wie CHECK-Einschränkungen. (Aber wirkt sich das Weglassen des PRIMARY KEY dann auf Kinder aus?)
Antwort auf hinzugefügte Frage
Wäre es nicht besser, wenn dieses widersprüchliche CREATE TABLE genau dort fehlschlagen würde?
Wie oben erläutert, ist dies
foo_id INTEGER NULL PRIMARY KEY
entspricht (derzeit) zu 100 %:
foo_id INTEGER PRIMARY KEY
Seit NULL
wird in diesem Zusammenhang als Füllwort behandelt.
Und wir möchten nicht, dass letzteres scheitert. Das ist also keine Option.