Может ли уникальный индекс WHERE, который позволяет использовать несколько NULL, в качестве первичного ключа для отношения внешнего ключа? - PullRequest
0 голосов
/ 24 февраля 2020

Использование SQL Сервер на Azure: 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 подходит в качестве первичного ключа для отношения внешнего ключа к TableForeign? Каждое значение, отличное от NULL, должно быть уникальным, и NULL во внешней таблице в любом случае не будет создавать отношения внешнего ключа. Но я получаю сообщение об ошибке при попытке установить отношение внешнего ключа на TableForeign.

Невозможно создать отношение 'FK_TableForeign_TablePrimary'.
В ссылочной таблице нет первичных ключей или ключей-кандидатов ' dbo.TablePrimary ', который соответствует списку ссылающихся столбцов во внешнем ключе' FK_TableForeign_TablePrimary '.

Прежде чем углубиться в это, я хотел бы убедиться, что то, что я пытаюсь сделать, действительно возможно , По сути, не в каждой строке в TablePrimary будут дети в TableForeign. Но те строки, которые существуют в TableForeign, должны иметь соответствие PrimaryId в TablePrimary (есть другие способы выполнить работу, но в этом случае мне понадобится третья таблица в качестве перекрестной ссылки между TablePrimary и TableForeign, и я хотел бы избежать этого, если это не нужно, хотя, если это необходимо, то это необходимо).

1 Ответ

1 голос
/ 25 февраля 2020

Может ли уникальный индекс WHERE, который позволяет использовать несколько NULL, в качестве первичного ключа для отношения внешнего ключа?

Нет. На уникальные отфильтрованные индексы нельзя ссылаться по внешним ключам. Внешние ключи могут ссылаться на уникальные индексы (даже с включенными столбцами, но без фильтров).

edit: для Nullability. Внешние ключи могут ссылаться на уникальные индексы / ограничения с NULLable столбцами. Обнуляемость не является обязательным условием для создания внешних ключей. Однако внешние ключи НЕ проверяются на наличие строк с хотя бы одним нулевым значением в любом из столбцов 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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...