我有一个错误

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)。快速搜索谷歌可以发现索引的最大长度是450个字符。然而,这并不能解释什么是解决方案。我如何创建像字典的键和值都是字符串,显然键必须是唯一的,是单一的?我的sql语句

create table [misc_info] (
[id] INTEGER PRIMARY KEY IDENTITY NOT NULL,
[key] nvarchar(max) UNIQUE NOT NULL,
[value] nvarchar(max) NOT NULL);

一种解决方案是将密钥声明为nvarchar(20)。


唯一的解决方案是在唯一索引中使用更少的数据。您的密钥最多可以是NVARCHAR(450)。

SQL Server对所有索引键列的最大总大小保留了900字节的限制。

在MSDN上阅读更多


唯一约束不能超过每行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个字符。


注意到klaisbyskov关于你的密钥长度需要十亿字节大小的评论,并且假设你确实需要这个,那么我认为你唯一的选择是:

使用键值的散列 在nchar(40)上创建一个列(例如用于sha1哈希), 在哈希列上放置唯一键。 在保存或更新记录时生成散列 触发在插入或更新时查询现有匹配的表。

哈希有一个警告,即有一天你可能会遇到碰撞。

触发器将扫描整个表。

轮到你了……


在SQL Server(直到2008 R2)中有一个限制,varchar(MAX)和nvarchar(MAX)(以及其他一些类型,如text, ntext)不能在索引中使用。你有两个选择: 1. 在关键字段上设置限制大小ex. nvarchar(100) 2. 创建一个检查约束,将值与表中的所有键进行比较。 条件为:

([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

但请注意,本机索引比检查约束性能更好,所以除非您确实无法指定长度,否则不要使用检查约束。