因为PRIMARY KEY
makes包含的列NOT NULL
自动地。我引用手册在这里 https://www.postgresql.org/docs/current/sql-createtable.html:
主键约束指定一个或多个列
表只能包含唯一(非重复)、非空值。
从技术上来说,PRIMARY KEY
只是一个组合UNIQUE
and NOT NULL
.
大胆强调我的。
我进行了测试来确认NOT NULL
与一个组合是完全多余的PRIMARY KEY
约束(在当前实现中,在版本 13 中重新测试)。这NOT NULL
约束保持即使在删除 PK 约束之后,无论显式如何NOT NULL
创建时的子句。
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
数据库小提琴
相同的行为如果NULL
包含在CREATE TABLE
陈述。
保留仍然不会有什么坏处NOT NULL
如果该列应该是,则在代码存储库中是多余的NOT NULL
。如果您稍后决定更改 PK 约束,您可能会忘记标记该列NOT NULL
- 或者它是否应该是NOT NULL
.
有一个Postgres TODO wiki 中的项目 https://wiki.postgresql.org/wiki/Todo#CREATE解耦NOT NULL
来自PK约束。所以这可能会在未来的版本中改变:
将 NOT NULL 约束信息移至 pg_constraint
当前 NOT NULL 约束存储在 pg_attribute 中,没有任何其来源的指定,例如主键。一份舱单
问题是删除 PRIMARY KEY 约束并不会删除
NOT NULL 约束指定。另一个问题是我们应该
可能会强制 NOT NULL 从父表传播到
子项,就像 CHECK 约束一样。 (但随后下降
主键影响儿童吗?)
回答添加的问题
如果这个自相矛盾的 CREATE TABLE 只是
就在那里失败了?
如上所述,这
foo_id INTEGER NULL PRIMARY KEY
(目前)100% 相当于:
foo_id INTEGER PRIMARY KEY
Since NULL
在这种情况下被视为干扰词。
我们不希望后者失败。所以这不是一个选择。