Риск столкновения UUID с использованием разных алгоритмов

У меня есть база данных, где 2 (или, может быть, 3 или 4) разных приложения вводят информацию. Новая информация имеет идентификаторы GUID GUID/UUID, но каждое приложение использует другой алгоритм для генерации идентификаторов. Например, один использует NHibernate "guid.comb", другой использует SQLServer NEWID(), другие могут использовать реализацию .NET Guid.NewGuid().

Существует ли выше нормальный риск столкновения или дублирования идентификатора?

Спасибо!

Ответ 1

Риск столкновения слегка повышается, но все еще исчезающе мал. Предположим, что:

  • Оба Comb и NEWID/NEWSEQUENTIALID включают метку времени с точностью до нескольких мс . Таким образом, если вы не генерируете большое количество идентификаторов в тот же момент времени из всех этих разных источников, буквально невозможно, чтобы идентификаторы сталкивались.

  • Часть GUID, которая не основана на временной метке, может считаться случайной; большинство GUID-алгоритмов основывают эти цифры на PRNG. Таким образом, вероятность столкновения между этими другими 10 байтами или около того находится в том же порядке, как если бы вы использовали два отдельных генератора случайных чисел и наблюдали за конфликтами.

    Подумайте об этом на мгновение - PRNG могут и повторяют числа, поэтому вероятность столкновения между двумя из них не намного выше, чем столкновение, используя только один из них, даже если они используют несколько разные алгоритмы. Это похоже на то, чтобы каждую неделю играть одни и те же номера лотереи против выбора случайного набора каждую неделю - шансы на выигрыш одинаковы в любом случае.

Теперь имейте в виду, что когда вы используете такой алгоритм, как Guid.Comb, у вас есть только 10 бит уникального идентификатора, что равно 1024 отдельным значениям. Поэтому, если вы создаете огромное количество GUID в течение нескольких миллисекунд, вы получите столкновений. Но если вы создаете GUID с довольно низкой частотой, на самом деле не имеет значения, сколько разных алгоритмов вы используете одновременно, вероятность столкновения по-прежнему практически отсутствует.

Лучший способ для вас быть абсолютно уверенным - запустить тест; имеют все 2 или 3 (или, как многие из вас), генерируя GUID, в то же время, через равные промежутки времени и записывая их в файл журнала, и видите, возникают ли у вас столкновения (и если да, то сколько). Это должно дать вам хорошее представление о том, насколько безопасно это на практике.

P.S. Если вы используете генератор гребня NHibernate для генерации идентификаторов GUID для кластерного первичного ключа, рассмотрите возможность использования NEWSEQUENTIALID() вместо NEWID() - вся суть Comb заключается в том, чтобы избежать разделения страниц, и вы не выполняете это, если у вас есть другой процессов с использованием несекретных алгоритмов. Вы также должны изменить любой код с помощью Guid.NewGuid, чтобы использовать тот же самый генератор расчёта - фактический алгоритм Comb, используемый в NHibernate, не сложный и легко дублируется в вашей собственной логике домена.

† Обратите внимание, что, по-видимому, существует некоторый спор о NEWID и содержит ли он временную метку. В любом случае, поскольку он основан на MAC-адресе, диапазон возможных значений значительно меньше, чем GUID V4 или Comb. Дальнейшая причина для меня рекомендовать придерживаться Comb GUID вне базы данных и NEWSEQUENTIALID внутри базы данных.

Ответ 2

Да, риск выше нормы, потому что все они используют разные определения "GUID". Guid.NewGuid() является RFC-совместимым главным образом случайным GUID, но NEWSEQUENTIALID является переупорядоченным (и, следовательно, не совместимым с RFC) GUID на основе MAC-адреса и метки времени, а GUID-интерфейс NHibernate полностью отличается (на основе случайности и временной метки).

Вы можете рассмотреть возможность стандартизации только одной реализации GUID. Я использую свой собственный гребенный GUID для всех моих приложений. Мой блог содержит краткие описания всех этих типов GUID вместе с дизайнерскими решениями для моих собственных.