是一种在索引中用作键列无效的types
我有一个错误
Column 'key' in table 'misc_info' is of a type that is invalid for use as a key column in an index.
其中key是一个nvarchar(max)。 快速谷歌发现这一点 。 但是它并不能解释什么是解决scheme。 我如何创build像字典那样的关键和价值都是string,显然这个关键必须是唯一的,是单一的。 我的SQL语句是
create table [misc_info] ( [id] INTEGER PRIMARY KEY IDENTITY NOT NULL, [key] nvarchar(max) UNIQUE NOT NULL, [value] nvarchar(max) NOT NULL);
唯一的约束不能超过每行8000字节,并且只使用前900个字节,所以最安全的密钥大小是:
create table [misc_info] ( [id] INTEGER PRIMARY KEY IDENTITY NOT NULL, [key] nvarchar(450) UNIQUE NOT NULL, [value] nvarchar(max) NOT NULL )
即密钥不能超过450个字符。 如果可以切换到varchar而不是nvarchar(例如,如果您不需要存储来自多个代码页的字符),那么可以增加到900个字符。
在SQL Server中有一个限制(直到2008 R2)varchar(MAX)和nvarchar(MAX)(以及像text,ntext这样的其他几个types)不能在索引中使用。 你有2个选项:
1.在关键字段ex上设置有限的尺寸。 为nvarchar(100)
2.创build一个检查约束,将该值与表中的所有键进行比较。 条件是:
([dbo].[CheckKey]([key])=(1))
和[dbo]。[CheckKey]是一个标量函数,定义如下:
CREATE FUNCTION [dbo].[CheckKey] ( @key nvarchar(max) ) RETURNS bit AS BEGIN declare @res bit if exists(select * from key_value where [key] = @key) set @res = 0 else set @res = 1 return @res END
但是请注意,本地索引比检查约束性能更高,因此除非真的不能指定长度,否则不要使用检查约束。
唯一的解决scheme是在您的唯一索引中使用更less的数据。 您的密钥最多可以是NVARCHAR(450)。
“SQL Server保留所有索引键列的最大总大小的900字节限制”。
阅读更多在MSDN
解决办法是将你的密钥声明为nvarchar(20)
。
注意到klaisbyskov关于你的密钥长度需要是千兆字节的评论,并假设你确实需要这个,那么我认为你唯一的select是:
- 使用键值的散列
- 在nchar(40)上创build一个列(例如对于sha1哈希),
- 把一个唯一的关键在哈希列。
- 在保存或更新logging时生成哈希
- 触发器在插入或更新时查询表的现有匹配。
哈希带来的警告有一天,你可能会碰撞。
触发器将扫描整个表格。
对你来说…