在多个 nvarchar(max) 列上建立索引

ana*_*sso 3 index sql-server sql-server-2012

我的数据库中有多个 nvarchar(max) 列,名为ShipperName, ConsigneeName, ProdDesc, BillOFLading

我需要做的是将UNIQUE INDEX这些列组合起来。因为我没有这样做,因为如果 900 B 限制。

然后我尝试了(阅读以下链接Indexing Wide Keys 后

ALTER TABLE dbo.ProductDetail 
   ADD ShipperNameHash AS HASHBYTES('SHA2_512', ShipperName) PERSISTED;

ALTER TABLE dbo.ProductDetail 
   ADD ConsigneeNameHash AS HASHBYTES('SHA2_512', ConsigneeName) PERSISTED;
Run Code Online (Sandbox Code Playgroud)

然后我在以下语句中遇到以下错误:

消息 8152,级别 16,状态 10,第 1 行
字符串或二进制数据将被截断。
该语句已终止。

ALTER TABLE dbo.ProductDetail 
   ADD ProductDescHash AS HASHBYTES('SHA2_512', Product_Description) PERSISTED;
Run Code Online (Sandbox Code Playgroud)

而且还创建了上面的语句列varbinary(8000)。这当然没有为我解决问题。

有什么方法可以建立UNIQUE INDEX在这些列的组合上吗?

Mic*_*art 7

我知道这已经得到了回答,但我将投票支持使用 HASHBYTES。我在我的帖子http://michaeljswart.com/2013/11/hashing-for-indexes/ 中谈了一点,我在下面描述了这种情况下的样子:

如果你可以使用 nvarchar(4000) 而不是 nvarchar(max),那么这个模式就变得可行了:

CREATE TABLE ProductDetail
(
    ProductDetailId INT IDENTITY PRIMARY KEY,
    ShipperName NVARCHAR(4000),
    ShipperNameHash as HASHBYTES('SHA1', ShipperName) PERSISTED,
    ConsigneeName  NVARCHAR(4000),
    ConsigneeNameHash  as HASHBYTES('SHA1', ConsigneeName) PERSISTED,
    UNIQUE(ShipperNameHash, ConsigneeNameHash )
)
go
Run Code Online (Sandbox Code Playgroud)

创建它时,SQL Server 会警告您该唯一索引的最大键长度超过 900 字节。但实际上,SHA1 永远不会返回超过 20 个字节,因此在这种特殊情况下,警告是可以忽略的。

看到它适用于这个插入语句

insert ProductDetail (ShipperName, ConsigneeName)
values 
(
  REPLICATE(N'A', 3999) + N'B', 
  REPLICATE(N'A', 3999) + N'B'
),
(
  REPLICATE(N'A', 3999) + N'C', 
  REPLICATE(N'A', 3999) + N'C'
)
Run Code Online (Sandbox Code Playgroud)

看到它失败了这个插入语句:

insert ProductDetail (ShipperName, ConsigneeName)
values 
(
  REPLICATE(N'A', 4000),
  REPLICATE(N'A', 4000)
),
(
  REPLICATE(N'A', 4000),
  REPLICATE(N'A', 4000)
)
Run Code Online (Sandbox Code Playgroud)