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

Identificatore univoco vs. IDENTITÀ vs. Codice materiale -- qual è la scelta migliore per la chiave primaria?

GUID può sembrare una scelta naturale per la tua chiave primaria - e se proprio devi, potresti probabilmente obiettare di usarla per la CHIAVE PRIMARIA della tabella. Cosa consiglio vivamente di non fare è utilizzare il GUID colonna come chiave di cluster , operazione che SQL Server esegue per impostazione predefinita, a meno che tu non specifichi espressamente di non farlo.

Devi davvero tenere separati due problemi:

  1. la chiave primaria è un costrutto logico, una delle chiavi candidate che identifica in modo univoco e affidabile ogni riga della tabella. Può essere qualsiasi cosa, davvero:un INT , un GUID , una stringa:scegli ciò che ha più senso per il tuo scenario.

  2. la chiave di raggruppamento (la colonna o le colonne che definiscono l'"indice cluster" nella tabella) - questo è un fisico cosa relativa allo storage, e qui, un tipo di dati piccolo, stabile e in continua crescita è la scelta migliore - INT o BIGINT come opzione predefinita.

Per impostazione predefinita, la chiave primaria su una tabella di SQL Server viene utilizzata anche come chiave di clustering, ma non è necessario che sia così! Personalmente ho riscontrato enormi miglioramenti delle prestazioni suddividendo la precedente chiave primaria/cluster basata su GUID in due chiavi separate:la chiave primaria (logica) sul GUID e la chiave di raggruppamento (ordinamento) su un INT IDENTITY(1,1) separato colonna.

Come Kimberly Tripp - la Regina dell'indicizzazione - e altri hanno affermato molte volte - un GUID poiché la chiave di clustering non è ottimale, poiché a causa della sua casualità, porterà a un'enorme frammentazione di pagine e indici e a prestazioni generalmente scadenti.

Sì, lo so:c'è newsequentialid() in SQL Server 2005 e versioni successive, ma anche questo non è veramente e completamente sequenziale e quindi soffre degli stessi problemi del GUID - solo un po' meno prominente.

Poi c'è un altro problema da considerare:la chiave di clustering su una tabella verrà aggiunta a ogni voce di ogni indice non cluster sulla tabella, quindi vuoi davvero assicurarti che sia il più piccolo possibile. Tipicamente, un INT con oltre 2 miliardi di righe dovrebbe essere sufficiente per la stragrande maggioranza delle tabelle e rispetto a un GUID come chiave di clustering, puoi risparmiare centinaia di megabyte di spazio di archiviazione su disco e nella memoria del server.

Calcolo rapido - utilizzando INT rispetto a GUID come chiave primaria e di clustering:

  • Tabella di base con 1'000'000 di righe (3,8 MB contro 15,26 MB)
  • 6 indici non cluster (22,89 MB contro 91,55 MB)

TOTALE:25 MB contro 106 MB - e questo è solo su un unico tavolo!

Qualche altro spunto di riflessione - materiale eccellente di Kimberly Tripp - leggilo, rileggilo, digeriscilo! È davvero il vangelo dell'indicizzazione di SQL Server.

A meno che tu non abbia un ottimo motivo , direi di usare un INT IDENTITY per quasi tutte le tabelle di dati "reali" come valore predefinito per la loro chiave primaria:è univoca, è stabile (non cambia mai), è stretta, è in continuo aumento:tutte le buone proprietà che vuoi avere in una chiave di clustering per prestazioni veloci e affidabili delle tue tabelle di SQL Server!

Se hai un valore chiave "naturale" che ha anche tutte quelle proprietà, potresti anche usarlo invece di una chiave surrogata. Ma due stringhe di lunghezza variabile di max. 20 caratteri ciascuno non soddisfano tali requisiti secondo me.