PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Warum kann ich eine Tabelle mit PRIMARY KEY für eine Nullable-Spalte erstellen?

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.