2009-10-30 10 views
9

SQL Server fornisce il tipo [rowguid]. Mi piace usare questo come chiave primaria univoca, per identificare una riga per l'aggiornamento. Il vantaggio si presenta se si scarica la tabella e la si ricarica, senza problemi con le colonne SerialNo (identità).È una buona idea usare rowguid come chiave unica nella progettazione del database?

Nel caso speciale di database distribuiti come copie non in linea su notebook o qualcosa del genere, nient'altro funziona.

Cosa ne pensi? Troppo sovraccarico?

risposta

18

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

+0

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. –

+0

@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! –

+0

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. –

6

Il problema con rowguid è che se lo si utilizza per l'indice cluster si finisce costantemente a ricalcolare le pagine della tabella per inserire i record. Un guid sequenziale (NEWSEQUENTIALID()) spesso funziona meglio.

+0

Interessante ma non funziona completamente perché, secondo la documentazione MSDN, il GUID sequenziale è sequenziale solo da quando l'ultimo computer è stato avviato e creerà valori più bassi in futuro. –

1

La nostra applicazione offline viene utilizzata nelle filiali e abbiamo un database centrale nella nostra sede principale. Per sincronizzare il database nel database centrale abbiamo usato la colonna rowguid in tutte le tabelle. Possono esserci soluzioni migliori ma è più facile per noi. Non abbiamo affrontato alcun problema importante fino alla data negli ultimi 3 anni.

1

Contrariamente alla risposta accettata, il tipo di dati uniqueidentifier in SQL Server è davvero un buon candidato per una chiave di clustering primaria; fintanto che lo mantieni sequenziale.

Questa operazione può essere facilmente eseguita utilizzando (newsequentialid()) come valore predefinito per la colonna.

Se si legge effettivamente Kimberly Tripp's article, si scoprirà che i GUID generati in sequenza sono in realtà un buon candidato per le chiavi di clustering primarie in termini di frammentazione e l'unico lato negativo è la dimensione.

Se si dispone di righe grandi con pochi indici, i pochi byte in eccesso in un GUID potrebbero essere trascurabili. Sicuri i problemi di emissione se hai file brevi con numerosi indici, ma questo è qualcosa che devi valutare a seconda della tua situazione.

L'utilizzo di identificatori univoci sequenziali ha molto senso quando si utilizza la replica di tipo merge, in particolare quando si ha a che fare con il seeding delle identità e i problemi che ne derivano.

Lo spazio di archiviazione del server non è economico, ma preferirei avere un database che utilizza un po 'più spazio di uno che si interrompe quando gli intervalli di identità assegnati automaticamente si sovrappongono.

Problemi correlati