Подтвердить что ты не робот

Как создать ограничение по нескольким столбцам в SQL Server

У меня есть таблица, которая содержит, например, два поля, которые я хочу сделать уникальными в базе данных. Например:

create table Subscriber (
    ID int not null,
    DataSetId int not null,
    Email nvarchar(100) not null,
    ...
)

Идентификационный столбец является первичным ключом, и индексируются как DataSetId, так и Email.

То, что я хочу сделать, - это предотвратить появление одной и той же комбинации электронной почты и DataSetId в таблице, или, говоря иначе, значение электронной почты должно быть уникальным для данного DataSetId.

Я попытался создать уникальный индекс в столбцах

CREATE UNIQUE NONCLUSTERED INDEX IX_Subscriber_Email
ON Subscriber (DataSetId, Email)

но я обнаружил, что это оказало значительное влияние на время поиска (например, при поиске адреса электронной почты - в таблице содержится 1,5 миллиона строк).

Существует ли более эффективный способ достижения такого ограничения?

4b9b3361

Ответ 1

но я обнаружил, что это оказало значительное влияние на время поиска (например, при поиске адреса электронной почты

Указанный вами индекс (DataSetId, Email) не может использоваться для поиска по электронной почте. Если вы создадите индекс с полем Email в крайнем левом положении, его можно использовать:

CREATE UNIQUE NONCLUSTERED INDEX IX_Subscriber_Email
   ON Subscriber (Email, DataSetId);

Этот индекс будет служить сервером как в качестве уникального принудительного принуждения, так и в качестве средства быстрого поиска электронной почты. Этот индекс не может быть использован для быстрого поиска определенного DataSetId.

Суть его в том, что всякий раз, когда вы определяете мультикидный индекс, его можно использовать только для поиска в порядке ключей. Индекс на (A, B, C) можно использовать для поиска значений в столбце A, для поиска значений на A и B или для поиска значений во всех трех столбцах A, B и C. Однако он не может использоваться для поиска значений только на B или только на C.

Ответ 2

Я предполагаю, что только путь ввода данных в эту таблицу осуществляется через SP. Если в этом случае вы можете реализовать некоторую логику в своих вставках и обновлениях SP, чтобы узнать, существуют ли значения, которые вы собираетесь вставлять/обновлять, в этом таблицы или нет.

Что-то вроде этого

create proc spInsert
(
    @DataSetId int,
    @Email nvarchar(100)
)
as
begin

if exists (select * from tabaleName where DataSetId = @DataSetId and Email = @Email)
    select -1 -- Duplicacy flag
else
begin
    -- insert logic here
    select 1 -- success flag
end

end
GO


create proc spUpdate
(
   @ID int,
   @DataSetId int,
   @Email nvarchar(100)
)
as
begin

if exists 
(select * from tabaleName where DataSetId = @DataSetId and Email = @Email and ID <> @ID)
    select -1 -- Duplicacy flag
else
begin
    -- insert logic here
    select 1 -- success flag
end

end
GO