允许多个NULLS的UNIQUE 'WHERE'索引可以用作外键关系的主键吗?
Can a UNIQUE 'WHERE' index which allows multiple NULLS be used as the primary key for a foreign key relationship?
在 Azure 上使用 SQL 服务器:12.0.2000.8
我已经为 TablePrimary
定义了以下唯一索引:
CREATE UNIQUE NONCLUSTERED INDEX [IX_TablePrimary_Id]
ON [dbo].[TablePrimary] ([PrimaryId] ASC)
WHERE [PrimaryId] IS NOT NULL
WHERE
子句允许多行在该列中有NULL
,但该列中的每个非NULL值必须是唯一的。
TablePrimary
中的索引列应该是 suitable 作为与 TableForeign
的外键关系的主键吗?每个非 NULL 值都必须是唯一的,并且外部 table 中的 NULL 无论如何都不会创建外键关系。但是我在尝试将外键关系放在 TableForeign
.
上时遇到错误
Unable to create relationship 'FK_TableForeign_TablePrimary'.
There are no primary or candidate keys in the referenced table 'dbo.TablePrimary' that match the referencing column list in the foreign key 'FK_TableForeign_TablePrimary'.
在我深入研究之前,我想验证我正在尝试做的事情确实可行。基本上,并非 TablePrimary
中的每一行都会在 TableForeign
中有子项。但是 TableForeign
中确实存在的那些行必须在 TablePrimary
中有匹配的 PrimaryId
(还有其他方法可以完成工作,但在这种情况下,我需要第三个 table 作为 TablePrimary
和 TableForeign
之间的交叉引用,如果没有必要,我想避免这种情况,尽管如果有必要,那么它就是必要的)。
Can a UNIQUE 'WHERE' index which allows multiple NULLS be used as the
primary key for a foreign key relationship?
没有。唯一过滤索引不能被外键引用。
唯一索引(即使包含列,虽然没有过滤器)可以被外键引用。
编辑:可空性。外键可以引用具有 NULLable 列的唯一 indexes/constraints。可为空性不是创建外键的先决条件。但是,不会检查任何 fk 列中至少有一个空值的行的外键:
create table dbo.parent
(
id1 int null,
id2 int null,
constraint id1id2 unique(id1, id2)
);
insert into dbo.parent(id1, id2)
values(1, 1), (2, 2), (3, null);
go
create table dbo.child
(
childid int identity,
parentid1 int,
parentid2 int,
constraint fkparent foreign key(parentid1, parentid2) references parent(id1, id2)
)
go
insert into dbo.child(parentid1, parentid2)
values (1, 1), (2, 2) --ok
go
insert into dbo.child(parentid1, parentid2)
values (4, 4) -- fk violation, there is no 4,4 parent row
go
insert into dbo.child(parentid1, parentid2)
values (3, null) --do not get tricked here.... because the fk has a null value, the fk is NOT checked at all
go
--fk with one null value, fk is not checked at all
insert into dbo.child(parentid1, parentid2)
values (100, null) -- but there is no 100, null parent row
go
select *
from parent;
select *
from child;
在 Azure 上使用 SQL 服务器:12.0.2000.8
我已经为 TablePrimary
定义了以下唯一索引:
CREATE UNIQUE NONCLUSTERED INDEX [IX_TablePrimary_Id]
ON [dbo].[TablePrimary] ([PrimaryId] ASC)
WHERE [PrimaryId] IS NOT NULL
WHERE
子句允许多行在该列中有NULL
,但该列中的每个非NULL值必须是唯一的。
TablePrimary
中的索引列应该是 suitable 作为与 TableForeign
的外键关系的主键吗?每个非 NULL 值都必须是唯一的,并且外部 table 中的 NULL 无论如何都不会创建外键关系。但是我在尝试将外键关系放在 TableForeign
.
Unable to create relationship 'FK_TableForeign_TablePrimary'.
There are no primary or candidate keys in the referenced table 'dbo.TablePrimary' that match the referencing column list in the foreign key 'FK_TableForeign_TablePrimary'.
在我深入研究之前,我想验证我正在尝试做的事情确实可行。基本上,并非 TablePrimary
中的每一行都会在 TableForeign
中有子项。但是 TableForeign
中确实存在的那些行必须在 TablePrimary
中有匹配的 PrimaryId
(还有其他方法可以完成工作,但在这种情况下,我需要第三个 table 作为 TablePrimary
和 TableForeign
之间的交叉引用,如果没有必要,我想避免这种情况,尽管如果有必要,那么它就是必要的)。
Can a UNIQUE 'WHERE' index which allows multiple NULLS be used as the primary key for a foreign key relationship?
没有。唯一过滤索引不能被外键引用。 唯一索引(即使包含列,虽然没有过滤器)可以被外键引用。
编辑:可空性。外键可以引用具有 NULLable 列的唯一 indexes/constraints。可为空性不是创建外键的先决条件。但是,不会检查任何 fk 列中至少有一个空值的行的外键:
create table dbo.parent
(
id1 int null,
id2 int null,
constraint id1id2 unique(id1, id2)
);
insert into dbo.parent(id1, id2)
values(1, 1), (2, 2), (3, null);
go
create table dbo.child
(
childid int identity,
parentid1 int,
parentid2 int,
constraint fkparent foreign key(parentid1, parentid2) references parent(id1, id2)
)
go
insert into dbo.child(parentid1, parentid2)
values (1, 1), (2, 2) --ok
go
insert into dbo.child(parentid1, parentid2)
values (4, 4) -- fk violation, there is no 4,4 parent row
go
insert into dbo.child(parentid1, parentid2)
values (3, null) --do not get tricked here.... because the fk has a null value, the fk is NOT checked at all
go
--fk with one null value, fk is not checked at all
insert into dbo.child(parentid1, parentid2)
values (100, null) -- but there is no 100, null parent row
go
select *
from parent;
select *
from child;