我注意到MATCH SIMPLEMATCH FULL,但我不明白它们的作用。我看到默认是MATCH SIMPLE;但是,约束函数MATCH的其他FOREIGN KEY子句又如何呢?

#1 楼

检查手册的CREATE TABLE页面:


共有三种匹配类型:MATCH FULLMATCH PARTIALMATCH SIMPLE
(默认设置)。 MATCH FULL除非多列外键的所有列
为空,否则不允许多列外键的一列为空;如果它们全为空,则不需要该行在引用表中具有
匹配项。 MATCH SIMPLE允许任何外键
为空;如果它们中的任何一个为null,则不需要行
在引用表中具有匹配项。 MATCH PARTIAL尚未实现。 (当然,可以将NOT NULL约束应用于
引用列,以防止出现这种情况。)


此外,在外键一章中: br />

通常,如果引用行的任何引用列为null,则不必满足外键约束。如果将MATCH FULL
添加到外键声明中,则仅当其所有引用列均为null时,引用行才能转义
满足约束(因此可以确保null和非null值的混合)使MATCH FULL
约束失败)。如果您不希望引用行能够
避免满足外键约束,请将引用
列声明为NOT NULL


请确保参考当前手册或与您的安装相匹配的版本。不要因为过时的Google链接而过时了。

#2 楼


FULLSIMPLEPARTIAL


虽然选择的答案是正确的,但如果这对您来说是新的,您可能希望使用代码查看它-我认为这样做更容易


-- 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
);


逻辑上,使用FULLSIMPLE,我们可以插入完全匹配项。 />当其中一列是NULL时出现问题。

-- works
INSERT INTO t_full (a,b) VALUES (1,1);
INSERT INTO t_simple (a,b) VALUES (1,1);


插入t_full会产生以下错误,

-- works
INSERT INTO t_simple (a,b) VALUES (1,NULL);

-- fails
INSERT INTO t_full (a,b) VALUES (1,NULL);


好,那么(42,NULL)怎么办?这是我经常对MATCH SIMPLE感到困惑的部分,

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


以上行为无法解决未实现的MATCH PARTIAL,它可能对您想要的最右边一列NULL的复合索引做了什么。但是,有人认为这是一种将Pandora盒子打开以进行不良设计的方法。

简单定义和助记符





MATCH FULL一切都必须完全匹配,或者所有列都必须为NULL。如果一个东西为MATCH SIMPLE,则约束被简单地忽略。

如果一个东西为NULL,则事实并非所有事情都是通过约束来做一些有意义的事情来挽救MATCH PARTIAL

SQL规范说明

为了后代,这里是SQL规范中有关NULL如果至少一个引用列为空,则引用表的行通过约束检查。如果所有引用列都不为空,则该行通过约束检查if
,并且仅在被引用表的行与所有引用列匹配的情况下通过。

NULL:如果所有引用列都为null,则引用表的行通过约束检查。如果至少一个引用列不为null,则该行通过约束检查,并且仅当被引用表中的行与所有非空引用列匹配时才行。

<match type>:如果所有引用列均为空,则引用表的行通过约束检查。如果所有引用列都不为空,则当且仅当被引用表的行与所有引用列匹配时,该行才通过约束检查。如果某个引用列为null,而另一个引用列为非null,则引用表的行违反了约束。
检查。





虽然这不是特定于PostgreSQL的,但这些示例已通过PostgreSQL进行了演示

评论


这个例子实际上完成了Erwin的解释!就我而言,我对Erwin不太了解,但我确实理解了所提供的示例。显然,对于仅涉及一列的外键而言,匹配简单,完全,部分匹配没有任何意义,对吗?

–维克多
20 Sep 23 '23:42