Porque la PRIMARY KEY
hace la(s) columna(s) incluida(s) NOT NULL
automáticamente . Cito el manual aquí:
La restricción de clave principal especifica que una columna o columnas de una tabla solo pueden contener valores únicos (no duplicados) no nulos. Técnicamente, PRIMARY KEY
es simplemente una combinación de UNIQUE
y NOT NULL
.
Énfasis en negrita mío.
Realicé una prueba para confirmar que NOT NULL
es completamente redundante en combinación con una PRIMARY KEY
restricción (en la implementación actual, reprobada en la versión 13). El NOT NULL
la restricción permanece incluso después de descartar la restricción PK, independientemente de un NOT NULL
explícito cláusula en el momento de la creación.
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<>violín aquí
Comportamiento idéntico si NULL
está incluido en CREATE TABLE
declaración.
Todavía no hará daño mantener NOT NULL
de forma redundante en repositorios de código si se supone que la columna es NOT NULL
. Si luego decide modificar la restricción PK, es posible que olvide marcar la columna NOT NULL
- o incluso si se suponía que era NOT NULL
.
Hay un elemento en el wiki TODO de Postgres para desacoplar NOT NULL
de la restricción PK. Así que esto podría cambiar en futuras versiones:
Mueva la información de restricción NOT NULL a pg_constraint
Actualmente, las restricciones NOT NULL se almacenan en pg_attribute sin ninguna designación de sus orígenes, p. claves primarias. Un problema manifiesto es que eliminar una restricción PRIMARY KEY no elimina la designación de restricción NOT NULL. Otro problema es que probablemente deberíamos forzar que NOT NULL se propague de las tablas principales a las secundarias, al igual que las restricciones CHECK. (Pero entonces, ¿dejar PRIMARY KEY afecta a los niños?)
Respuesta a la pregunta añadida
¿No sería mejor si esta autocontradictoria CREATE TABLE simplemente fallara allí mismo?
Como se explicó anteriormente, este
foo_id INTEGER NULL PRIMARY KEY
es (actualmente) 100 % equivalente a:
foo_id INTEGER PRIMARY KEY
Desde NULL
se trata como palabra irrelevante en este contexto.
Y no nos gustaría que esta última fallara. Así que esta no es una opción.