è di un tipo che non è valido per l’uso come colonna chiave in un indice

Ho un errore in

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

dove key è un nvarchar (max). Un rapido google ha trovato questo . Tuttavia non spiega quale sia una soluzione. Come faccio a creare qualcosa come Dizionario in cui la chiave e il valore sono entrambe stringhe e ovviamente la chiave deve essere unica ed è unica. La mia affermazione di sql era

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

Un vincolo univoco non può essere superiore a 8000 byte per riga e utilizzerà solo i primi 900 byte anche in quel momento, quindi la dimensione massima più sicura per le chiavi sarebbe:

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

cioè la chiave non può contenere più di 450 caratteri. Se è ansible passare a varchar anziché a nvarchar (ad esempio, se non è necessario memorizzare i caratteri da più di una codepage), potrebbe aumentare fino a 900 caratteri.

Esiste una limitazione in SQL Server (fino al 2008 R2) che varchar (MAX) e nvarchar (MAX) (e molti altri tipi come text, ntext) non possono essere utilizzati negli indici. Hai 2 opzioni:
1. Impostare una dimensione limitata sul campo chiave es. nvarchar (100)
2. Creare un vincolo di controllo che confronta il valore con tutte le chiavi nella tabella. La condizione è:

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

e [dbo]. [CheckKey] è una funzione scalare definita come:

 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 

Tuttavia, si noti che un indice nativo è più performante di un vincolo di controllo, quindi, a meno che non si possa davvero specificare una lunghezza, non utilizzare il vincolo di controllo.

L’unica soluzione è usare meno dati nel tuo Indice Unico. La tua chiave può essere NVARCHAR (450) al massimo.

“SQL Server conserva il limite di 900 byte per la dimensione totale massima di tutte le colonne della chiave dell’indice.”

Maggiori informazioni su MSDN

Una soluzione sarebbe dichiarare la tua chiave come nvarchar(20) .

Osservando il commento di klaisbyskov sulla lunghezza della chiave che deve essere di dimensioni gigabyte, e supponendo che sia effettivamente necessario, allora penso che le tue uniche opzioni siano:

  1. usa un hash del valore chiave
    • Creare una colonna su nchar (40) (per un hash sha1, per esempio),
    • metti una chiave univoca sulla colonna dell’hash.
    • genera l’hash durante il salvataggio o l’aggiornamento del record
  2. si innesca per interrogare la tabella per una corrispondenza esistente su inserimento o aggiornamento.

Hashing arriva con l’avvertenza che un giorno potresti avere una collisione.

I trigger eseguiranno la scansione dell’intero tavolo.

A voi…