如何在SQL Server中的NVARCHAR(MAX)列上强制实现唯一性?

时间:2011-07-22 16:57:14

标签: sql-server sql-server-2008-r2

我在SQL Server 2008 R2中有一个NVARCHAR(MAX)列。我想在该列上设置唯一索引,但唯一索引中包含的列的最大大小为NVARCHAR(450)或900字节。

如何在NVARCHAR(MAX)列上强制实现唯一性?

谢谢!

4 个答案:

答案 0 :(得分:5)

  1. 在某种哈希上创建一个持久列,例如CHECKSUM。例如:Hash = MyStringHash作为CHECKSUM(MyString)
  2. 在该列上创建非唯一索引
  3. 创建一个强制唯一性的触发器。需要索引来加速EXISTS子句中的搜索:

            WHERE   NOT EXISTS ( SELECT 1
                                 FROM   YourTable AS y
                                 WHERE  y.MyStringHash = CHECKSUM(Inserted.MyString)
                                        AND y.MyString = Inserted.MyString) ;
    
  4. 重要提示:您需要针对整理进行测试。如果您使用不区分大小写的排序规则,请确保该触发器不允许“MyTest”和“MYTEST”。

    如果你选择一个独特的索引并停下来,你只是在创建一个等待发生的错误。

    编辑:在不区分大小写的环境中,我使用了CHECKSUM作为持久计算列,它快速,不区分大小写,并且选择性足够。

答案 1 :(得分:3)

我和Cory有同样的想法。假设与SHA1的冲突不太可能,您可以执行以下操作:

CREATE TABLE [dbo].[tblHash](
    [s] [nvarchar](MAX) NOT NULL,
    [h]  AS (hashbytes('SHA1',[s])) PERSISTED,
    CONSTRAINT [IX_tblHash] UNIQUE NONCLUSTERED (
        [h]
    )
)

答案 2 :(得分:2)

您可以对NVARCHAR(MAX)字段使用某种散列函数,并在散列字段上创建UNIQUE INDEX。

修改

正如Yuck所指出的,随着哈希函数的工作方式,你可能会遇到碰撞的可能性。如果你使用像SHA1这样的哈希,那么(可能)你很可能会发生冲突。

答案 3 :(得分:1)

你如何拥有一个你担心重复的大字段?

一种方法是创建像LEFT(NvarCharMaxField, 200)这样的计算字段,并在上添加唯一索引。除此之外,我认为除非你添加一个触发器,否则会有一种方法,而且非常昂贵。