2010-05-19 16 views
123

Tengo un error enes de un tipo que no es válido para su uso como una columna de clave en un índice

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

donde clave es un nvarchar (max). Un rápido google found this. Sin embargo, no explica qué es una solución. ¿Cómo creo algo como Dictionary donde la clave y el valor son ambas cadenas y, obviamente, la clave debe ser única y es única. Mi instrucción SQL era

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

¿Realmente necesita que su llave sea (potencialmente) 4GB grande Y única? SqlServer no permite esto porque verificar la unicidad podría ser una operación ** muy ** que consume mucho tiempo. –

Respuesta

4

Una solución sería declarar su clave como nvarchar(20).

9

La única solución es utilizar menos datos en su índice único. Su clave puede ser NVARCHAR (450) como máximo.

"SQL Server conserva el límite de 900 bytes para el tamaño total máximo de todas las columnas de clave de índice".

Lea más en MSDN

+0

Para varchar, ¿el límite seguiría siendo varchar (450)? – Steam

183

una restricción única no puede ser más de 8000 bytes por fila y sólo se utilizarán los primeros 900 bytes incluso entonces por lo que el tamaño máximo más segura para sus llaves sería:

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

es decir, la clave no puede tener más de 450 caracteres. Si puede cambiar a varchar en lugar de nvarchar (por ejemplo, si no necesita almacenar caracteres de más de una página de códigos), entonces podría aumentar a 900 caracteres.

+0

Para varchar, ¿el límite seguiría siendo varchar (450)? – Steam

+5

Tiene espacio para usar 'varchar (900)' OR 'nvarchar (450)'. –

+0

Según tengo entendido, un varchar tendrá 4 bytes para determinar la longitud del elemento, lo que significa que el límite real debe ser varchar (896). ¿Es esto correcto? – mrmillsy

2

Observando el comentario de klaisbyskov sobre su longitud de clave que necesitan ser gigabytes de tamaño, y suponiendo que lo hace, de hecho, necesita esto, entonces creo que sus únicas opciones son:

  1. usar un hash del valor de la clave
    • crear una columna en nchar (40) (para un hash SHA1, por ejemplo),
    • poner una clave única en la columna de la matriz.
    • generar el hash al guardar o actualizar el registro
  2. disparadores para consultar la tabla para una coincidencia existente en la inserción o actualización.

Hashing viene con la advertencia de que un día, usted puede ser que obtener una colisión.

Los disparadores escanearán toda la tabla.

Usted tiene la palabra ...

19

Hay una limitación en SQL Server (hasta el 2008 R2) que VARCHAR (MAX) y nvarchar (MAX) (y varios otros tipos como texto, ntext) no se puede utilizar en índices. Tiene 2 opciones:
1. Establezca un tamaño limitado en el campo clave ex. nvarchar (100)
2. Cree una restricción de verificación que compare el valor con todas las claves de la tabla. La condición es:

([dbo].[CheckKey]([key])=(1)) 

y [dbo].[CheckKey] es una función escalar definida como:

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 

Pero tenga en cuenta que un índice nativa es más performante que una restricción de comprobación por lo menos que realmente no se puede especificar una longitud, no utilice la restricción de comprobación.

+0

Inteligente: más agradable que los desencadenantes, creo. –

Cuestiones relacionadas