sql >> Base de Datos >  >> RDS >> PostgreSQL

¿Por qué puedo crear una tabla con PRIMARY KEY en una columna anulable?

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.