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

Rischio di collisione UUID utilizzando diversi algoritmi

Il rischio di collisioni è leggermente elevato ma è ancora evanescente. Considera che:

  • Sia Comb che NEWID /NEWSEQUENTIALID includere un timestamp con precisione fino a pochi ms. Pertanto, a meno che tu non stia generando un numero elevato di ID nello esatto stesso momento da tutte queste diverse fonti, è letteralmente impossibile per la collisione degli ID.

  • La parte del GUID che non è in base al timestamp può essere considerato casuale; la maggior parte degli algoritmi GUID basa queste cifre su un PRNG. Pertanto, la probabilità di una collisione tra questi altri 10 byte o giù di lì è dello stesso ordine come se si utilizzassero due generatori di numeri casuali separati e si osservassero le collisioni.

    Pensaci per un momento:i PRNG possono e ripetono numeri, quindi la probabilità di una collisione tra due di loro non è significativamente maggiore di una collisione utilizzando solo uno di essi, anche se utilizzano algoritmi leggermente diversi. È un po' come giocare gli stessi numeri della lotteria ogni settimana anziché scegliere un set casuale ogni settimana:le probabilità di vincita sono esattamente le stesse in entrambi i casi.

Ora, tieni presente che quando usi un algoritmo come Guid.Comb, hai solo 10 bit di unificatore, che equivalgono a 1024 valori separati. Quindi, se stai generando un numero enorme di GUID negli stessi pochi millisecondi, farai ottenere collisioni. Ma se generi GUID a una frequenza abbastanza bassa, non importa quanti algoritmi utilizzi contemporaneamente, la probabilità di una collisione è ancora praticamente inesistente.

Il modo migliore per essere assolutamente certi è eseguire un test; avere tutti e 2 o 3 (o quanti ne usi) che generano GUID, allo stesso tempo, a intervalli regolari, e scrivili in un file di registro e vedi se ottieni collisioni (e in tal caso, quante). Questo dovrebbe darti una buona idea di quanto sia sicuro in pratica.

PS Se stai utilizzando il generatore di pettini di NHibernate per generare GUID per una chiave primaria in cluster, considera l'utilizzo di NEWSEQUENTIALID() invece di NEWID() - il punto centrale di Comb è evitare le divisioni di pagina e non lo stai realizzando se hai altri processi che utilizzano algoritmi non sequenziali. Dovresti anche cambiare qualsiasi codice usando Guid.NewGuid utilizzare lo stesso generatore Comb:l'attuale algoritmo Comb utilizzato in NHibernate non è complicato e facile da duplicare nella tua logica di dominio.

† ​​Nota che sembra esserci qualche disputa su NEWID e se contiene o meno un timestamp. In ogni caso, poiché si basa sull'indirizzo MAC, l'intervallo di valori possibili è notevolmente inferiore rispetto a un GUID V4 oa un Comb. Un ulteriore motivo per cui ti consiglio di attenermi ai Comb GUID al di fuori del database e di NEWSEQUENTIALID all'interno del database.