A-K*_*A-K 24 postgresql ddl constraints primary-key postgresql-9.3
以下代码创建表而不引发任何错误:
CREATE TABLE test(
ID INTEGER NULL,
CONSTRAINT PK_test PRIMARY KEY(ID)
)
Run Code Online (Sandbox Code Playgroud)
请注意,我无法按预期插入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).
Run Code Online (Sandbox Code Playgroud)
为什么我可以创建一个具有自相矛盾定义的表格?ID列显式声明为NULLable,并且作为PRIMARY KEY的一部分,它隐式地不可为空.是否有意义?
编辑:如果这个自相矛盾的CREATE TABLE在那里失败了会不会更好?
Erw*_*ter 33
由于PRIMARY KEY 使列NOT NULL 自动.我在这里引用手册:
主键约束指定表的一列或多列只能包含唯一(非重复)非空值.从技术上讲,
PRIMARY KEY仅仅是UNIQUE和的结合NOT NULL.
大胆强调我的.
我运行了一个测试,以确认(与我以前的信念相反!)NOT NULL与PRIMARY KEY约束相结合是完全冗余的(在当前实现中,直到版本9.5).删除PK约束后,NOT NULL约束仍然存在,无论NOT NULL创建时的显式子句如何.
db=# CREATE TEMP TABLE foo (foo_id int PRIMARY KEY);
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "foo_pkey" for table "foo"
CREATE TABLE
db=# ALTER TABLE foo DROP CONSTRAINT foo_pkey;
ALTER TABLERun Code Online (Sandbox Code Playgroud)
db=# \d foo
table »pg_temp_4.foo«
column | type | attribute
--------+---------+-----------
foo_id | integer | not nullRun Code Online (Sandbox Code Playgroud)
如果声明中NULL包含相同的行为CREATE.
但是,NOT NULL如果列应该是在代码存储库中保持冗余仍然不会有害NOT NULL.如果你以后决定移动pk约束,你可能会忘记标记列NOT NULL- 或者它是否应该是NOT NULL.
Postgres TODO wiki中有一个项目可以与NOT NULLPK约束分离.所以这可能会在未来的版本中改变:
将NOT NULL约束信息移动到pg_constraint
目前,NOT NULL约束存储在pg_attribute中,而不指定其起源,例如主键.一个明显的问题是删除PRIMARY KEY约束不会删除NOT NULL约束指定.另一个问题是我们应该强制NOT NULL从父表传播到子表,就像CHECK约束一样.(但是,丢弃PRIMARY KEY会影响孩子吗?)
如果这个自相矛盾的CREATE TABLE就在那里失败了,那会不会更好?
如上所述,这
foo_id INTEGER NULL PRIMARY KEY
Run Code Online (Sandbox Code Playgroud)
相当于:
foo_id INTEGER PRIMARY KEY
Run Code Online (Sandbox Code Playgroud)
因为NULL被视为噪音词.
我们不希望后者失败.所以这不是一个选择.
| 归档时间: |
|
| 查看次数: |
14701 次 |
| 最近记录: |