唯一索引上的外键不适用于NULL列

时间:2017-01-02 10:51:29

标签: sql-server database

我在SQL Server中的一个唯一索引上使用外键时遇到了困难,这个索引并没有按预期工作。

我的表结构是这样的:

  • 表mm1在代理键列id上具有非聚簇PK-Index
    • 此外,mm1在三列上有一个聚簇唯一索引(其中一列可以为空)
    • 表mm2通过外键链接这三列

创建这些对象不会产生任何错误。但是,外键未正确评估,并允许将mm1中的不存在值插入mm2中。这似乎与可空列c相关....如果我只在列a和b上设置外键它按预期工作。

你能解释一下这种行为吗?为什么允许首先定义一个包含null的唯一索引,但在外键约束中不能正确支持它?有没有办法在不改变表格mm2的内容的情况下获得正确的结果?

这是一个小的repro脚本:

CREATE table mm1 (
    id int identity(1,1) NOT NULL,
    a varchar(50) not null,     
    b int not null, 
    c int null, 
    PRIMARY KEY NONCLUSTERED(id))

CREATE table mm2 (
    id int identity(1,1) NOT NULL,
    a varchar(50) not null,
    b int not null,
    c int null,
    d varchar(10),
    PRIMARY KEY NONCLUSTERED(id))

CREATE  UNIQUE CLUSTERED INDEX  idx_mm1_mm_fkTest1 ON mm1(a,b,c)

ALTER TABLE mm2
ADD CONSTRAINT  fk_mm2_mm_fkTest1 
FOREIGN KEY (a,b, c)  REFERENCES mm1(a,b,c)

ALTER TABLE mm2 CHECK CONSTRAINT fk_mm2_mm_fkTest1;

INSERT INTO mm1 VALUES ('abc', 1, 2);

INSERT INTO mm2 
(a,b,d) VALUES('sa',1,'sad')

SELECT * FROM mm2;

1 个答案:

答案 0 :(得分:2)

我完全不确定我期望这样做。我想的越多,它的意义就越小。

在这些上下文中计算NULL意味着UNKNOWN。对于外键中的未知,您可能永远无法确定它首先引用哪一行。换句话说,这种约束没有语义意义。

使用默认值并使外键仅触及非空值。如果你在外键中允许NULL,那么无论如何都会悬空。