2012-04-18 10 views

risposta

15

Sto cercando di generare ID univoci per l'identificazione di alcuni dati nel mio sistema.

mi consiglia un GUID poi, dal momento che sono, per definizione, identificatori univoci globali.

Sto usando un sistema elaborato che concatena alcuni (non unici, rilevanti) metadati con System.Guid.NewGuid(). Ci sono degli svantaggi in questo approccio, o sono in chiaro?

Bene, dal momento che non sappiamo cosa si considera un inconveniente, è difficile da dire. Mi vengono in mente alcuni possibili inconvenienti:

  • GUID sono grandi: 128 bit sono un sacco di bit.

  • GUID non garantisce una distribuzione particolare; è perfettamente legale per generare GUID in modo sequenziale ed è perfettamente legale che sia distribuito uniformemente nello spazio di 124 bit (128 bit meno i quattro bit che sono ovviamente il numero di versione). Ciò può avere gravi conseguenze sul database prestazioni se il GUID viene utilizzato come chiave primaria in un database che viene indicizzato nell'ordine ordinato dal GUID; gli inserimenti sono molto più efficienti se la nuova riga va sempre alla fine. Un GUID uniformemente distribuito sarà quasi uguale a mai alla fine.

  • GUID versione 4 sono pseudo-casuali ma non crittograficamente casuali; un utente malintenzionato potrebbe in teoria prevedere quali sono i tuoi GUID quando viene fornito un campione rappresentativo di essi. Un utente malintenzionato potrebbe in teoria determinare la probabilità che due GUID siano stati generati nella stessa sessione. I GUID della versione uno sono ovviamente quasi casuali e possono dire al lettore sofisticato quando e dove sono stati generati.

  • E così via.

Sto pianificando una serie di articoli su queste e altre caratteristiche di GUID nelle prossime due settimane; guarda il mio blog per i dettagli.

+0

Ho pensato che ci fosse uno spazio a 122 bit disponibile basato su questo: http://blogs.msdn.com/b/oldnewthing/archive/2008/06/27/ 8659071.aspx Sta parlando della stessa implementazione? –

7

Quando si utilizza System.Guid.NewGuid(), è possibile controllare che il guid non sia già presente nel sistema.

Mentre un guid è così complesso da essere virtualmente unico, non c'è nulla che garantisca che non esiste già tranne la probabilità. È solo incredibilmente statisticamente improbabile, al punto che in ogni caso è lo stesso di essere unico.

Generare a guidi identici è come vincere la lotteria due volte - non c'è nulla che impedisca effettivamente, è così improbabile che potrebbe anche essere impossibile.

La maggior parte delle volte è probabile che tu possa scappare senza cercare partite esistenti, ma in un caso estremo con un sacco di generazione in corso, o dove il sistema non deve assolutamente fallire, potrebbe valerne la pena.

EDIT

Vorrei chiarire un po 'di più. È altamente improbabile che tu possa mai vedere una guida doppia. Questo è il punto. È "globalmente unico", nel senso che c'è una tale possibilità infinitamente di un duplicato che si può presumere che sarà unico. Tuttavia, se stiamo parlando di un codice che tiene un aereo in cielo, controlla un reattore nucleare o gestisce il supporto vitale sulla Stazione Spaziale Internazionale, personalmente, controllerei personalmente un duplicato, solo perché sarebbe davvero terribile colpire quel caso limite. Se stai semplicemente scrivendo un motore di blog, d'altra parte, vai avanti, usalo senza controllo.

5

Sentitevi liberi di usare NewGuid(). Non c'è nessun problema con la sua unicità.

C'è una probabilità troppo bassa che generi lo stesso guid due volte; un bell'esempio può essere trovato qui: Simple proof that GUID is not unique

var bigHeapOGuids = new Dictionary<Guid, Guid>(); 
try 
{ 
    do 
    { 
     Guid guid = Guid.NewGuid(); 
     bigHeapOGuids.Add(guid ,guid); 
    } while (true); 
} 
catch (OutOfMemoryException) 
{ 
} 

Ad un certo punto si è bloccato sulla OutOfMemory e non sul conflitto chiave duplicata.

+1

Questo è un cattivo esempio. Un 'HashSet' non lancia un'eccezione sull'aggiunta di un elemento duplicato, semplicemente non lo aggiunge. Ecco perché restituisce un valore booleano che indica se è stato aggiunto qualcosa. – hvd

+0

@hvd: corretto asnwer. Metti un 'dizionario ' e prova nuovamente. Il risultato è lo stesso: nessun conflitto chiave, ma eccezione di memoria. Grazie! – Tigran

+0

Non che nessuno di noi si aspettasse altro, ovviamente :) – hvd

Problemi correlati