46 postgresql foreign-key constraint referential-integrity ddl
我注意到了MATCH SIMPLE和MATCH FULL,但我不明白它们是做什么的。我看到默认是MATCH SIMPLE; 但是,约束函数的其他MATCH子句如何FOREIGN KEY?
Erw*_*ter 55
共有三种匹配类型:
MATCH FULL、MATCH PARTIAL和MATCH SIMPLE(这是默认值)。MATCH FULL除非所有外键列都为空,否则不允许多列外键的一列为空;如果它们都为空,则该行不需要在引用的表中具有匹配项。MATCH SIMPLE允许任何外键列为空;如果它们中的任何一个为空,则该行不需要在引用的表中具有匹配项。MATCH PARTIAL尚未实施。(当然,NOT NULL可以对引用列应用约束以防止出现这些情况。)
通常,如果引用行的任何引用列为空,则引用行不需要满足外键约束。如果
MATCH FULL添加到外键声明中,则仅当引用行的所有引用列都为空时,引用行才会满足约束条件(因此,空值和非空值的混合保证使MATCH FULL约束失败)。如果您不希望引用行避免满足外键约束,请将引用列声明为NOT NULL.
并确保查阅当前手册或与您的安装匹配的版本。不要被过时的谷歌链接指向过时的版本。
Eva*_*oll 23
FULL对比SIMPLE对比PARTIAL虽然选择的答案是正确的,但如果这对您来说是新的,您可能希望通过代码查看它——我认为这样更容易理解。
-- one row with (1,1)
CREATE TABLE foo ( a int, b int,
PRIMARY KEY (a,b)
);
INSERT INTO foo (a,b) VALUES (1,1);
--
-- two child tables to reference it
--
CREATE TABLE t_full ( a int, b int,
FOREIGN KEY (a,b) REFERENCES foo MATCH FULL
);
CREATE TABLE t_simple ( a int, b int,
FOREIGN KEY (a,b) REFERENCES foo MATCH SIMPLE
);
Run Code Online (Sandbox Code Playgroud)
从逻辑上讲,使用FULLand SIMPLE,我们可以插入一个完整的匹配项。
-- works
INSERT INTO t_full (a,b) VALUES (1,1);
INSERT INTO t_simple (a,b) VALUES (1,1);
Run Code Online (Sandbox Code Playgroud)
当其中一列是NULL.
-- works
INSERT INTO t_simple (a,b) VALUES (1,NULL);
-- fails
INSERT INTO t_full (a,b) VALUES (1,NULL);
Run Code Online (Sandbox Code Playgroud)
插入到t_full生成以下错误,
ERROR: insert or update on table "t_full" violates foreign key constraint "t_full_a_fkey"
DETAIL: MATCH FULL does not allow mixing of null and nonnull key values.
INSERT 0 1
Run Code Online (Sandbox Code Playgroud)
好的,那怎么办(42,NULL)——这是我一直觉得困惑的部分MATCH SIMPLE,
-- works
INSERT INTO t_simple (a,b) VALUES (42,NULL);
Run Code Online (Sandbox Code Playgroud)
上述行为将不工作,未实现的MATCH PARTIAL,这可能是你想要什么,其中最右边的列是一个复合索引NULL编出来。然而,有些人认为这是打开潘多拉魔盒接受糟糕设计的一种方法。
MATCH FULL一切都必须完全匹配,或者所有列都必须是NULLMATCH SIMPLE如果一件事是NULL约束被简单地忽略。MATCH PARTIAL如果有一件事是NULL事实,不是一切都NULL被部分地通过做一些合理的约束的目的打捞上岸。对于后代,这里是 SQL 规范中的定义 <match type>
MATCH SIMPLE如果至少一个引用列为空,则引用表的行通过约束检查。如果所有引用列都不为空,则当且仅当引用表中存在与所有引用列匹配的行时,该行才会通过约束检查。MATCH PARTIAL: 如果所有引用列都为空,则引用表的行通过约束检查。如果至少一个引用列不为空,则当且仅当引用表的一行与所有非空引用列匹配时,该行才通过约束检查。MATCH FULL: 如果所有引用列都为空,则引用表的行通过约束检查。如果所有引用列都不为空,则当且仅当引用表中存在与所有引用列匹配的行时,该行才会通过约束检查。如果某个引用列为空而另一个引用列非空,则引用表的行违反约束检查。
虽然这不是 PostgreSQL 特定的,但这些示例是用 PostgreSQL 演示的
| 归档时间: |
|
| 查看次数: |
38420 次 |
| 最近记录: |