Ponieważ PRIMARY KEY
produkuje dołączone kolumny NOT NULL
automatycznie . Cytuję instrukcję tutaj:
Ograniczenie klucza podstawowego określa, że kolumna lub kolumny atable mogą zawierać tylko unikalne (nie zduplikowane) wartości inne niż null.Technicznie PRIMARY KEY
jest tylko kombinacją UNIQUE
i NOT NULL
.
Pogrubiony nacisk na moje.
Przeprowadziłem test, aby potwierdzić, że NOT NULL
jest całkowicie nadmiarowy w połączeniu z PRIMARY KEY
ograniczenie (w obecnej implementacji, ponownie przetestowane w wersji 13). NOT NULL
ograniczenie pozostaje nawet po usunięciu ograniczenia PK, niezależnie od jawnego NOT NULL
klauzula w czasie tworzenia.
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<>graj tutaj
Identyczne zachowanie, jeśli NULL
znajduje się w CREATE TABLE
oświadczenie.
Nadal nie zaszkodzi zachować NOT NULL
nadmiarowo w repozytoriach kodu, jeśli kolumna ma być NOT NULL
. Jeśli później zdecydujesz się zmienić ograniczenie PK, możesz zapomnieć o zaznaczeniu kolumny NOT NULL
- czy w ogóle miał być NOT NULL
.
W wiki Postgres TODO znajduje się element, który umożliwia rozdzielenie NOT NULL
z ograniczenia PK. Może się to zmienić w przyszłych wersjach:
Przenieś informacje o ograniczeniu NOT NULL do pg_constraint
Obecnie ograniczenia NOT NULL są przechowywane w pg_attribute bez podania ich pochodzenia, np. klucze podstawowe. Jednym z przejawów problemu jest to, że usunięcie ograniczenia KLUCZ PODSTAWOWY nie powoduje usunięcia oznaczenia ograniczenia NOT NULL. Inną kwestią jest to, że powinniśmy prawdopodobnie wymusić propagowanie wartości NOT NULL z tabel nadrzędnych do dzieci, tak jak w przypadku ograniczeń CHECK. (Ale czy porzucenie PRIMARY KEY wpływa na dzieci?)
Odpowiedź na dodane pytanie
Czy nie byłoby lepiej, gdyby ta wewnętrznie sprzeczna CREATE TABLE po prostu zawiodła?
Jak wyjaśniono powyżej, to
foo_id INTEGER NULL PRIMARY KEY
jest (obecnie) w 100% odpowiednikiem:
foo_id INTEGER PRIMARY KEY
Od NULL
jest traktowane jako słowo szumu w tym kontekście.
I nie chcielibyśmy, aby to drugie zawiodło. Więc to nie jest opcja.