Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Risco de colisão UUID usando algoritmos diferentes


O risco de colisões é ligeiramente elevado, mas ainda muito pequeno. Considere isso:

  • Ambos Pente e NEWID /NEWSEQUENTIALID inclua um carimbo de data/hora com precisão de alguns ms. Assim, a menos que você esteja gerando um grande número de IDs no exatamente no mesmo momento de todas essas fontes diferentes, é literalmente impossível para que os IDs colidam.

  • A parte do GUID que não é com base no timestamp pode ser considerado aleatório; a maioria dos algoritmos GUID baseia esses dígitos em um PRNG. Assim, a probabilidade de uma colisão entre esses outros 10 bytes ou mais está na mesma ordem como se você usasse dois geradores de números aleatórios separados e observasse colisões.

    Pense nisso por um momento - PRNGs podem e repetem números, então a probabilidade de uma colisão entre dois deles não é significativamente maior do que uma colisão usando apenas um deles, mesmo que eles usem algoritmos ligeiramente diferentes. É como jogar os mesmos números de loteria toda semana versus escolher um conjunto aleatório toda semana - as chances de ganhar são exatamente as mesmas de qualquer maneira.

Agora, tenha em mente que quando você usa um algoritmo como Guid.Comb, você tem apenas 10 bits de exclusivo, o que equivale a 1024 valores separados. Portanto, se você estiver gerando um grande número de GUIDs nos mesmos milissegundos, você vai obter colisões. Mas se você gerar GUIDs em uma frequência bastante baixa, não importa quantos algoritmos diferentes você use ao mesmo tempo, a probabilidade de uma colisão ainda é praticamente inexistente.

A melhor maneira de ter certeza absoluta é fazer um teste; tenha todos os 2 ou 3 (ou quantos você usar) gerando GUIDs, ao mesmo tempo, em intervalos regulares, e escreva-os em um arquivo de log e veja se você obtém colisões (e, em caso afirmativo, quantas). Isso deve lhe dar uma boa ideia de como isso é seguro na prática.

P.S. Se você estiver usando o gerador de combinação do NHibernate para gerar GUIDs para uma chave primária clusterizada, considere usar NEWSEQUENTIALID() em vez de NEWID() - o objetivo do Comb é evitar divisões de página, e você não está conseguindo isso se tiver outros processos usando algoritmos não sequenciais. Você também deve alterar qualquer código usando Guid.NewGuid para usar o mesmo gerador Comb - o algoritmo Comb real usado no NHibernate não é complicado e fácil de duplicar em sua própria lógica de domínio.

† ​​Observe que parece haver alguma disputa sobre NEWID , e se contém ou não um carimbo de data/hora. De qualquer forma, por se basear no endereço MAC, o intervalo de valores possíveis é consideravelmente menor que um GUID V4 ou um Comb. Mais uma razão para eu recomendar a utilização de Comb GUIDs fora do banco de dados e NEWSEQUENTIALID dentro do banco de dados.