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
在这些列的组合上吗?
我知道这已经得到了回答,但我将投票支持使用 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)