2012-02-02 3 views
11

Mi chiedo se esiste una migliore pratica di codifica per quanto riguarda la gestione degli ID per gli oggetti padre> padre nel codice, dove i record DB utilizzano un int incrementale automatico come ID (sul salvataggio iniziale). Naturalmente quando nel codice non si riesce a indovinare quale potrebbe essere questo ID e quindi è necessario lasciarlo vuoto e presumibilmente salvare tutti questi elementi in una transazione afferrando prima l'ID padre e quindi impostarlo su tutti i bambini prima di salvarliInves vs Auto incrementati

D'altra parte, i guidi sono molto più facili da gestire nel codice, poiché è possibile generare felicemente l'Id prima e impostarlo su tutto e salvare senza preoccupazioni.

c'è un modo semplice per gestire gli oggetti nel codice utilizzando auto-ints come le loro chiavi db?

grazie

risposta

29

GUID può sembrare una scelta naturale per la chiave primaria - e se proprio deve, probabilmente si potrebbe obiettare di usarlo per la chiave primaria della tabella. Quello che consiglio vivamente di non fare è utilizzare la colonna GUID come chiave di cluster , quale SQL Server esegue per impostazione predefinita, a meno che non lo si specifichi espressamente.

si ha realmente bisogno per mantenere due questioni a parte:

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

2) la clustering di chiave (la colonna o le colonne che definiscono il "indice cluster" a tabella) - questo è un fisico cosa archiviazione-correlati, e qui, un piccolo, stabile, crescente il tipo di dati è 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 assistito a massicci guadagni in termini di prestazioni quando suddivido la precedente chiave primaria/basata su GUID in due chiavi separate: la chiave primaria (logica) sul GUID e la chiave di clustering (ordinamento) su INT INTENTITÀ separata (1, 1) colonna.

Come Kimberly Tripp come la Regina dell'Indicizzazione - e altri hanno dichiarato molte volte - un GUID come chiave di clustering non è ottimale, poiché a causa della sua casualità, porterà a massiccia frammentazione di pagine e indici e generalmente cattiva prestazione.

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

Quindi c'è un altro problema da considerare: la chiave di clustering su un tavolo verrà aggiunta a ogni voce su ogni singolo indice non cluster sul tuo tavolo, quindi assicurati che sia tanto piccola quanto possibile. In genere, un INT con oltre 2 miliardi di righe dovrebbe essere sufficiente per la stragrande maggioranza delle tabelle e, confrontato con un GUID come chiave di clustering, è possibile risparmiare centinaia di megabyte di spazio su disco e nella memoria del server.

Calcolo veloce - utilizzando INT vs.GUID primaria e Clustering chiave: Tabella

  • base con 1'000'000 righe (3.8 MB vs. 15.26 MB)
  • 6 non cluster indici (22.89 MB vs. 91.55 MB)

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

Ancora un po 'di spunti di riflessione - roba eccellente di Kimberly Tripp - leggilo, rileggilo, digeriscilo! È il gospel dell'indicizzazione di SQL Server, davvero.

anche: da un C#/.NET punto di vista - dipende da come si accede al database di SQL Server. Se si utilizza qualcosa come Linq-to-SQL o Entity Framework v4, gli oggetti .NET verranno automaticamente aggiornati con gli ID inseriti (dalla colonna INT IDENTITY) senza che sia necessario eseguire alcuna operazione. Quindi, per me, questa è una ragione in meno per cui si dovrebbe sentire il bisogno di utilizzare GUID di ....

GUID sono orribilmente male come SQL Server chiavi di clustering - non solo male - veramente, realmente, AWFUL

+0

+1 da parte mia per una spiegazione davvero buona. Grazie marc_s – Jehof

+0

Molto utile per coloro che non hanno una conoscenza approfondita di questi argomenti .. come me :-) – diggingforfire

+0

Ero già caduto in fallo del mio predecessore usando il Guid come chiave di cluster e non farò l'errore da solo :) Non sto usando linq -to-sql o quadro di entità .. forse vale la pena dare un'occhiata.poichè questi tavoli non avranno davvero un attacco in quanto tale, forse Guidi è la strada da seguire, stava solo cercando di tenersi alla larga da loro a meno che non dovessi davvero ... chiedendo quindi se ci fosse un modo astuto di usare gli Ints. . molte grazie per la tua risposta e il tempo utili .. chiedo se qualcuno potrebbe rispondere un po 'di più dal lato .net ..? – nat

2

Ci sono un paio di vantaggi di "codifica" per i GUID rispetto agli aggiornamenti automatici.

Prima è disaccoppiato, non è necessario accedere al database per ottenere un ID univoco quasi certamente.

Quindi è possibile creare un nuovo record in memoria, farlo conoscere e passare l'archiviazione effettiva a qualche servizio, quindi utilizzarlo felicemente per aggiungere localmente i dati correlati e quindi passarlo allo stesso o ad un altro servizio . Il correttivo che cose come EF si sono classificate per voi sotto le copertine sta trattando di dover inserire il record nel db e quindi ottenere l'identità del DBMS ad esso assegnato per passare alla funzionalità downstream. Puoi evitarlo se hai un'altra chiave univoca e l'auto inc è un surrogato, ma non è un pranzo gratis in nessun modo.

Se non stavo facendo distribuire e la mia app doveva essere connessa al database, e l'auto inc è un vero surrogato (non esposto come numero d'ordine o un po 'di tale intorpidimento), e int copriva l'intervallo, e lì non era possibile dire che due o i miei clienti si fondono e vogliono unire i loro database, quindi non mi preoccuperei di guidarli.

Affrontare il fatto di avere un'altra domanda per quanto mi riguarda. Ci sono problemi, ma sono banali se paragonati al fatto che la tua chiave unica non è unica.