имеет тип, который недопустим для использования в качестве столбца ключа в индексе

У меня есть ошибка в

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

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

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

163
задан 19 May 2010 в 08:46
поделиться

5 ответов

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

225
ответ дан 23 November 2019 в 21:18
поделиться

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

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

33
ответ дан 23 November 2019 в 21:18
поделиться

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

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

Подробнее см. MSDN

13
ответ дан 23 November 2019 в 21:18
поделиться

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

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

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

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

Перед вами ...

2
ответ дан 23 November 2019 в 21:18
поделиться

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

6
ответ дан 23 November 2019 в 21:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: