имеет недопустимый тип для использования в качестве ключевого столбца в индексе - PullRequest
157 голосов
/ 19 мая 2010

У меня ошибка на

Column 'key' in table 'misc_info' is of a type that is invalid for use as a key column in an index.

где ключ - это nvarchar (макс.) Быстрый Google нашел это . Однако это не объясняет, что такое решение. Как мне создать что-то вроде словаря, в котором ключ и значение являются строками и, очевидно, ключ должен быть уникальным и единственным Мое заявление было

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

Ответы [ 5 ]

220 голосов
/ 19 мая 2010

Уникальное ограничение не может превышать 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 символов.

32 голосов
/ 19 мая 2010

В SQL Server есть ограничение (до 2008 R2), что varchar (MAX) и nvarchar (MAX) (и некоторые другие типы, такие как text, ntext) не могут использоваться в индексах. У вас есть 2 варианта:
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

Но обратите внимание, что собственный индекс более производительный, чем проверочное ограничение, поэтому, если вы действительно не можете указать длину, не используйте проверочное ограничение.

12 голосов
/ 19 мая 2010

Единственное решение - использовать меньше данных в вашем уникальном индексе. Ваш ключ может быть не более NVARCHAR (450).

«SQL Server сохраняет ограничение в 900 байт для максимального общего размера всех столбцов ключа индекса.»

Подробнее на MSDN

6 голосов
/ 19 мая 2010

Решением было бы объявить ваш ключ как nvarchar(20).

2 голосов
/ 19 мая 2010

Принимая во внимание комментарий Клайсбыскова о том, что длина ключа должна быть в гигабайтах, и, если вы действительно нуждаетесь в этом, то я думаю, что единственные варианты:

  1. использовать хеш значения ключа
    • Создать столбец в nchar (40) (например, для хэша sha1),
    • поместите уникальный ключ в столбец хеша.
    • генерирует хеш при сохранении или обновлении записи
  2. вызывает запрос к таблице на предмет существующего совпадения при вставке или обновлении.

Хеширование идет с оговоркой, что однажды вы можете получить столкновение.

Триггеры будут сканировать всю таблицу.

За вами ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...