完全匹配,简单匹配和部分匹配之间的区别?


Answers:


38

检查CREATE TABLE手册页

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

另外,在“ 外键一章中

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

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


7

FULLvs SIMPLEvsPARTIAL

尽管选择的答案是正确的,但是如果这是您的新手,您可能希望通过代码查看它-我认为以这种方式更容易。

-- 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可以插入完全匹配项。

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

当列之一是时,问题就来了NULL

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

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

插入会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

好的,那又如何(42,NULL)-这是我经常感到困惑的部分MATCH SIMPLE

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

上述行为将工作,未实现的MATCH PARTIAL,这可能是你想要什么,其中最右边的列是一个复合索引NULL编出来。但是,有些人认为这是将潘多拉盒子打开到不良设计的一种方法。

简单定义和助记符

  • MATCH FULL一切都必须完全匹配,或者所有列都必须是NULL
  • MATCH SIMPLE如果有一件事是NULL在约束简单地忽略。
  • MATCH PARTIAL如果NULL事实是并非所有事情都可以通过为约束的目的而做一些明智的事情而NULL得到部分挽救。

SQL规范说明

为了后代,以下是SQL规范中有关 <match type>

  • MATCH SIMPLE如果至少一个引用列为null,则引用表的行通过约束检查。如果所有引用列都不为空,则当且仅当所引用表的行与所有引用列匹配时,该行才通过约束检查。
  • MATCH PARTIAL:如果所有引用列均为null,则引用表的行通过约束检查。如果至少一个引用列不为空,则该行通过约束检查,并且仅当被引用表中的行与所有非空引用列匹配时才行。
  • MATCH FULL:如果所有引用列均为null,则引用表的行通过约束检查。如果所有引用列都不为空,则当且仅当所引用表的行与所有引用列匹配时,该行才通过约束检查。如果某个引用列为null,而另一个引用列为非null,则引用表的行违反了约束检查。

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.