我有一个表,其中包含两个我希望在数据库中唯一的字段。例如:
create table Subscriber (
ID int not null,
DataSetId int not null,
Email nvarchar(100) not null,
...
)
ID列是主键,DataSetId和Email都被编入索引。
我希望能够阻止表中出现相同的Email和DataSetId组合,换句话说,对于给定的DataSetId,Email值必须是唯一的。
我尝试在列上创建唯一索引
CREATE UNIQUE NONCLUSTERED INDEX IX_Subscriber_Email
ON Subscriber (DataSetId, Email)
但我发现这对搜索时间产生了相当大的影响(例如,搜索电子邮件地址时 - 表格中有150万行)。
是否有更有效的方法来实现此类约束?
答案 0 :(得分:29)
但我发现这对搜索时间有很大影响 (例如,搜索电子邮件地址时
您在(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
上搜索值。
答案 1 :(得分:-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