Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Creazione di un indice su una variabile di tabella

La domanda è contrassegnata da SQL Server 2000, ma a beneficio delle persone che sviluppano sull'ultima versione affronterò prima questo problema.

SQL Server 2014

Oltre ai metodi di aggiunta di indici basati su vincoli illustrati di seguito, SQL Server 2014 consente anche di specificare gli indici non univoci direttamente con la sintassi inline nelle dichiarazioni di variabili di tabella.

Di seguito è riportato un esempio di sintassi.

/*SQL Server 2014+ compatible inline index syntax*/
DECLARE @T TABLE (
C1 INT INDEX IX1 CLUSTERED, /*Single column indexes can be declared next to the column*/
C2 INT INDEX IX2 NONCLUSTERED,
       INDEX IX3 NONCLUSTERED(C1,C2) /*Example composite index*/
);

Al momento, gli indici filtrati e gli indici con colonne incluse non possono essere dichiarati con questa sintassi, tuttavia SQL Server 2016 lo rilassa un po' di più. Da CTP 3.1 è ora possibile dichiarare indici filtrati per variabili di tabella. Per RTM può nel caso in cui siano consentite anche le colonne incluse, ma la posizione attuale è che "probabilmente non entreranno in SQL16 a causa di vincoli di risorse"

/*SQL Server 2016 allows filtered indexes*/
DECLARE @T TABLE
(
c1 INT NULL INDEX ix UNIQUE WHERE c1 IS NOT NULL /*Unique ignoring nulls*/
)

SQL Server 2000 - 2012

Posso creare un indice su Nome?

Risposta breve:Sì.

DECLARE @TEMPTABLE TABLE (
  [ID]   [INT] NOT NULL PRIMARY KEY,
  [Name] [NVARCHAR] (255) COLLATE DATABASE_DEFAULT NULL,
  UNIQUE NONCLUSTERED ([Name], [ID]) 
  ) 

Di seguito una risposta più dettagliata.

Le tabelle tradizionali in SQL Server possono avere un indice cluster o essere strutturate come heap.

Gli indici raggruppati possono essere dichiarati come univoci per non consentire valori di chiave duplicati o per impostazione predefinita non univoci. Se non è univoco, SQL Server aggiunge automaticamente un identificatore a tutte le chiavi duplicate per renderle univoche.

Gli indici non cluster possono anche essere dichiarati in modo esplicito come univoci. In caso contrario, per il caso non univoco, SQL Server aggiunge il localizzatore di riga (chiave di indice cluster o RID per un heap) a tutte le chiavi di indice (non solo ai duplicati), questo assicura nuovamente che siano univoche.

In SQL Server 2000 - 2012 gli indici sulle variabili di tabella possono essere creati solo in modo implicito creando un UNIQUE o PRIMARY KEY vincolo. La differenza tra questi tipi di vincolo è che la chiave primaria deve trovarsi su colonne non nullable. Le colonne che partecipano a un vincolo univoco possono essere annullabili. (sebbene l'implementazione di vincoli univoci da parte di SQL Server in presenza di NULL s non è conforme a quanto specificato nello standard SQL). Inoltre una tabella può avere solo una chiave primaria ma più vincoli univoci.

Entrambi questi vincoli logici sono implementati fisicamente con un indice univoco. Se non diversamente specificato, la PRIMARY KEY diventerà l'indice cluster e i vincoli univoci non cluster, ma questo comportamento può essere ignorato specificando CLUSTERED o NONCLUSTERED esplicitamente con la dichiarazione di vincolo (sintassi di esempio)

DECLARE @T TABLE
(
A INT NULL UNIQUE CLUSTERED,
B INT NOT NULL PRIMARY KEY NONCLUSTERED
)

Come risultato di quanto sopra, gli indici seguenti possono essere creati implicitamente su variabili di tabella in SQL Server 2000 - 2012.

+-------------------------------------+-------------------------------------+
|             Index Type              | Can be created on a table variable? |
+-------------------------------------+-------------------------------------+
| Unique Clustered Index              | Yes                                 |
| Nonunique Clustered Index           |                                     |
| Unique NCI on a heap                | Yes                                 |
| Non Unique NCI on a heap            |                                     |
| Unique NCI on a clustered index     | Yes                                 |
| Non Unique NCI on a clustered index | Yes                                 |
+-------------------------------------+-------------------------------------+

L'ultimo richiede un po' di spiegazione. Nella definizione della variabile di tabella all'inizio di questa risposta il non unico indice non cluster su Name è simulato da un unico indice su Name,Id (ricorda che SQL Server aggiungerebbe comunque la chiave dell'indice cluster alla chiave NCI non univoca).

È anche possibile ottenere un indice cluster non univoco aggiungendo manualmente un IDENTITY colonna per fungere da unificatore.

DECLARE @T TABLE
(
A INT NULL,
B INT NULL,
C INT NULL,
Uniqueifier INT NOT NULL IDENTITY(1,1),
UNIQUE CLUSTERED (A,Uniqueifier)
)

Ma questa non è una simulazione accurata di come un indice cluster non univoco verrebbe normalmente implementato in SQL Server poiché ciò aggiunge "Uniqueifier" a tutte le righe. Non solo quelli che lo richiedono.