gpt4 book ai didi

database - 为什么我可以在可为空的列上创建一个带有 PRIMARY KEY 的表?

转载 作者:行者123 更新时间:2023-11-29 11:08:36 24 4
gpt4 key购买 nike

以下代码创建一个表而不会引发任何错误:

CREATE TABLE test(
ID INTEGER NULL,
CONSTRAINT PK_test PRIMARY KEY(ID)
)

请注意,我无法按预期插入 NULL:

INSERT INTO test
VALUES(1),(NULL)
ERROR: null value in column "id" violates not-null constraint
DETAIL: Failing row contains (null).
********** Error **********

ERROR: null value in column "id" violates not-null constraint
SQL state: 23502
Detail: Failing row contains (null).

为什么我可以创建一个定义自相矛盾的表?作为 PRIMARY KEY 的一部分,ID 列显式声明为 NULLable,并且不可隐式为 NULL。有道理吗?

编辑:如果这个自相矛盾的 CREATE TABLE 就在那儿失败不是更好吗?

最佳答案

因为 PRIMARY KEY 使包含的列 NOT NULL 自动。我引用 the manual here :

The primary key constraint specifies that a column or columns of atable can contain only unique (non-duplicate), nonnull values.Technically, PRIMARY KEY is merely a combination of UNIQUE and NOT NULL.

大胆强调我的。

我运行了一个测试来确认 NOT NULLPRIMARY KEY 约束相结合是完全冗余的(在当前实现中,在版本 13 中重新测试)。即使在删除 PK 约束之后,NOT NULL 约束仍然存在,而不管创建时是否有显式的 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

db<> fiddle here

如果 NULL 包含在 CREATE TABLE 语句中,则行为相同。

如果该列应该是 NOT NULL,那么在代码存储库中冗余地保留 NOT NULL 仍然没有坏处。如果您稍后决定更改 PK 约束,您可能会忘记标记列 NOT NULL - 或者它是否应该是 NOT NULL

有一个item in the Postgres TODO wiki从 PK 约束中解耦 NOT NULL。所以这可能会在未来的版本中改变:

Move NOT NULL constraint information to pg_constraint

Currently NOT NULL constraints are stored in pg_attribute without any designation of their origins, e.g. primary keys. One manifestproblem is that dropping a PRIMARY KEY constraint does not remove theNOT NULL constraint designation. Another issue is that we shouldprobably force NOT NULL to be propagated from parent tables tochildren, just as CHECK constraints are. (But then does droppingPRIMARY KEY affect children?)

回答添加的问题

Would it not be better if this self-contradictory CREATE TABLE justfailed right there?

如上所述,这

foo_id INTEGER NULL PRIMARY KEY

(目前)100% 等同于:

foo_id INTEGER PRIMARY KEY

因为 NULL 在此上下文中被视为干扰词。
我们不希望后者失败。所以这不是一个选择。

关于database - 为什么我可以在可为空的列上创建一个带有 PRIMARY KEY 的表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20006374/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com