Porque a
PRIMARY KEY
faz as colunas incluídas NOT NULL
automaticamente . Cito o manual aqui:
A restrição de chave primária especifica que uma coluna ou colunas de uma tabela podem conter apenas valores exclusivos (não duplicados) não nulos. Tecnicamente,PRIMARY KEY
é apenas uma combinação deUNIQUE
eNOT NULL
.
Minha ênfase em negrito.
Fiz um teste para confirmar que
NOT NULL
é completamente redundante em combinação com uma PRIMARY KEY
restrição (na implementação atual, testada novamente na versão 13). O NOT NULL
restrição permanece mesmo depois de descartar a restrição PK, independentemente de um NOT NULL
explícito cláusula no momento da criação. 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<>mexa aqui
Comportamento idêntico se
NULL
está incluído no CREATE TABLE
demonstração. Ainda não fará mal manter
NOT NULL
redundantemente em repositórios de código se a coluna deve ser NOT NULL
. Se mais tarde você decidir alterar a restrição PK, pode esquecer de marcar a coluna NOT NULL
- ou se deveria ser NOT NULL
. Existe um item no wiki do Postgres TODO para desacoplar
NOT NULL
da restrição PK. Portanto, isso pode mudar em versões futuras:
Mover as informações de restrição NOT NULL para pg_constraint
Atualmente as restrições NOT NULL são armazenadas em pg_attribute sem qualquer designação de suas origens, por exemplo. chaves primárias. Um problema de manifesto é que descartar uma restrição PRIMARY KEY não remove a designação de restrição NOT NULL. Outra questão é que provavelmente devemos forçar NOT NULL a ser propagado de tabelas pai para filhas, assim como as restrições CHECK. (Mas então largar a CHAVE PRIMÁRIA afeta as crianças?)
Resposta à pergunta adicionada
Não seria melhor se esse CREATE TABLE autocontraditório simplesmente falhasse ali mesmo?
Como explicado acima, este
foo_id INTEGER NULL PRIMARY KEY
é (atualmente) 100% equivalente a:
foo_id INTEGER PRIMARY KEY
Desde
NULL
é tratado como palavra de ruído neste contexto.E não queremos que o último falhe. Portanto, esta não é uma opção.