26

例如,我有一个表,其中包含两个我想在数据库中唯一的字段。例如:

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

ID 列是主键,DataSetId 和 Email 都被索引。

我想要做的是防止相同的电子邮件和 DataSetId 组合出现在表中,或者换句话说,电子邮件值对于给定的 DataSetId 必须是唯一的。

我尝试在列上创建唯一索引

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

但我发现这对搜索时间有相当大的影响(例如,在搜索电子邮件地址时 - 表中有 150 万行)。

有没有更有效的方法来实现这种类型的约束?

4

2 回答 2

45

但我发现这对搜索时间有相当大的影响(例如在搜索电子邮件地址时

您定义的索引(DataSetId, Email)不能用于基于电子邮件的搜索。如果您要使用最左侧位置的字段创建索引Email,则可以使用它:

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

该索引既可以作为唯一的约束强制执行,也可以作为快速搜索电子邮件的一种手段。该索引虽然不能用于快速搜索特定的DataSetId.

它的要点是,无论何时定义多键索引,它都只能用于按键的顺序进行搜索。上的索引(A, B, C)可用于查找列上A的值、同时 A搜索和上的B值或搜索所有三列上的ABC。但是,它不能用于单独BC单独搜索值。

于 2012-08-01T08:00:17.353 回答
-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
于 2012-08-01T07:59:32.180 回答