我在 SQL Server 2008 R2 中有一个 NVARCHAR(MAX) 类型的列。我想在该列上设置唯一索引,但是作为唯一索引的列的最大大小为 NVARCHAR(450) 或 900 字节。
如何对 NVARCHAR(MAX) 列强制执行唯一性?
谢谢!
我在 SQL Server 2008 R2 中有一个 NVARCHAR(MAX) 类型的列。我想在该列上设置唯一索引,但是作为唯一索引的列的最大大小为 NVARCHAR(450) 或 900 字节。
如何对 NVARCHAR(MAX) 列强制执行唯一性?
谢谢!
Create a trigger that enforces uniqueness. The index is needed to speed up the search in EXISTS clause:
WHERE NOT EXISTS ( SELECT 1
FROM YourTable AS y
WHERE y.MyStringHash = CHECKSUM(Inserted.MyString)
AND y.MyString = Inserted.MyString) ;
重要提示:您需要根据您的排序规则进行测试。如果您使用的是不区分大小写的排序规则,请确保触发器不允许同时出现'MyTest'和'MYTEST'。
如果您只创建唯一索引并停止,那么您只是在等待出现错误的漏洞。
编辑:在不区分大小写的环境中,我使用了CHECKSUM用于持久计算列,这是快速、不区分大小写且足够有选择性的方法。
我和Cory有同样的想法。假设与SHA1碰撞的可能性足够小,你可以按照以下步骤操作:
CREATE TABLE [dbo].[tblHash](
[s] [nvarchar](MAX) NOT NULL,
[h] AS (hashbytes('SHA1',[s])) PERSISTED,
CONSTRAINT [IX_tblHash] UNIQUE NONCLUSTERED (
[h]
)
)
您如何拥有一个如此大的字段,以至于您担心会出现重复?
一种方法是创建一个计算字段,例如LEFT(NvarCharMaxField, 200)
,并对该字段放置唯一索引。除此之外,我认为没有其他方法,除非您添加触发器,但那将非常昂贵。
您可以对NVARCHAR(MAX)字段使用某种哈希函数,并在哈希字段上创建唯一索引。
编辑:
正如Yuck所指出的那样,由于哈希函数的工作方式,您可能会遇到冲突。 如果您使用SHA1等哈希,则可能性非常小,但仍有可能发生冲突。