Perché la PRIMARY KEY
fa le colonne incluse NOT NULL
automaticamente . Cito il manuale qui:
Il vincolo della chiave primaria specifica che una o più colonne di atable possono contenere solo valori univoci (non duplicati) e non nulli. Tecnicamente, PRIMARY KEY
è semplicemente una combinazione di UNIQUE
e NOT NULL
.
Enfasi in grassetto la mia.
Ho eseguito un test per confermare che NOT NULL
è completamente ridondante in combinazione con una PRIMARY KEY
vincolo (nell'attuale implementazione, ritestato nella versione 13). Il NOT NULL
il vincolo rimane anche dopo aver eliminato il vincolo PK, indipendentemente da un esplicito NOT NULL
clausola al momento della creazione.
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<>gioca qui
Comportamento identico se NULL
è incluso nel CREATE TABLE
dichiarazione.
Non farà comunque male mantenere NOT NULL
in modo ridondante nei repository di codice se la colonna dovrebbe essere NOT NULL
. Se in seguito decidi di modificare il vincolo PK, potresti dimenticare di contrassegnare la colonna NOT NULL
- o anche se doveva essere NOT NULL
.
C'è un elemento nella wiki di Postgres TODO per disaccoppiare NOT NULL
dal vincolo PK. Quindi questo potrebbe cambiare nelle versioni future:
Sposta le informazioni sul vincolo NOT NULL in pg_constraint
Attualmente i vincoli NOT NULL sono memorizzati in pg_attribute senza alcuna designazione delle loro origini, ad es. chiavi primarie. Un problema di manifest è che l'eliminazione di un vincolo PRIMARY KEY non rimuove la designazione del vincolo NOT NULL. Un altro problema è che probabilmente dovremmo forzare la propagazione di NOT NULL dalle tabelle padre ai figli, proprio come lo sono i vincoli CHECK. (Ma allora la caduta della CHIAVE PRIMARIA colpisce i bambini?)
Risposta alla domanda aggiunta
Non sarebbe meglio se questo contraddittorio CREATE TABLE fallisse proprio lì?
Come spiegato sopra, questo
foo_id INTEGER NULL PRIMARY KEY
è (attualmente) equivalente al 100 % a:
foo_id INTEGER PRIMARY KEY
Da NULL
viene trattata come una parola non comune in questo contesto.
E non vorremmo che quest'ultimo fallisse. Quindi questa non è un'opzione.