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 deUNIQUEeNOT 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.