Come chiave primaria in senso logico (identificando in modo univoco le righe) - sì, assolutamente, ha perfettamente senso.
MA: in SQL Server, la chiave primaria è di default anche la di clustering chiave sulla vostra tavola, e utilizzando un ROWGUID
come chiave di clustering è una davvero pessima idea. Vedere l'eccellente articolo GUIDs as a PRIMARY and/or the clustering key di Kimberly Tripp per ragioni approfondite per non utilizzare GUID per il clustering.
Dal momento che il GUID è casuale per definizione, si avrà una frammentazione di indice orribile e quindi una prestazione davvero negativa sulle istruzioni di inserimento, aggiornamento, eliminazione e selezione.
Inoltre, poiché la chiave di clustering viene aggiunta a ogni singolo campo di ogni indice non cluster sul tuo tavolo, stai sprecando molto spazio - sia su disco che nella RAM del server - quando utilizzando GUID a 16 byte rispetto a INT a 4 byte.
Quindi: sì, come chiave primaria, un ROWGUID ha i suoi meriti, ma se lo si usa, evitare assolutamente di usare quella colonna come chiave di clustering nella tabella! Usa INT IDENTITY() o qualcosa di simile per quello.
Per una chiave di clustering, idealmente si dovrebbe guardare per quattro caratteristiche:
- stabile (mai mutevoli)
- unica
- il più piccolo possibile
- sempre crescente
INT IDENTITY() si adatta idealmente a tale esigenza. E sì - la chiave di clustering deve essere univoca dato che è usata per localizzare fisicamente una riga nella tabella - se si sceglie una colonna che non può essere garantita come univoca, SQL Server aggiungerà effettivamente un unificatore a quattro byte alla chiave di clustering - di nuovo, non qualcosa che si desidera ...
Check out The Clustered Index Debate Continues - un altro articolo meraviglioso e perspicace di Kim Tripp (la "Queen of SQL Server Indexing") in cui spiega tutte queste esigenze molto bene e accuratamente .
Marc
fonte
2009-10-30 19:35:34
La dimensione del GUID non dovrebbe essere un problema qui. In risposta diretta alla domanda non c'è nulla di più offerto qui tranne un avviso "non dimenticare di scegliere un altro indice cluster". Poiché ROWGUID è anche l'ID riga internamente, non ci dovrebbe essere spazio sprecato in quanto il target dell'indice (l'ID della riga) verrà comunque scritto lì. O c'è un limite/mancanza di significato di ottimizzazione MS deve scrivere il GUID due volte nell'indice anche quando è il ROWGUID? Ne dubito, ma ti prego di chiarire se sai diversamente. –
@CodeChief: la dimensione della * chiave di clustering * è ** molto ** un problema in SQL Server! Dovrebbe essere il più piccolo possibile, poiché è incluso anche in ** tutti gli indici ** non cluster sulla stessa tabella. 4 byte contro 16 byte fa una differenza ** enorme ** se hai 100 milioni di righe e 15 indici non cluster! –
nel caso non fosse chiaro, sto VERAMENTE suggerendo che questo non ha nulla a che fare con gli indici cluster! Se si deve quindi DEFAULT NEWSEQUENTIALID() come documentato in MSDN e già risposto da altri qui. Ad ogni modo, parlando di database di grandi dimensioni, se si tratta di clienti importanti e importanti, è necessario pianificare la scalabilità o avere un requisito altamente disponibile, che comunque ritorna a ROWGUID. –