День 1285. #NuGet
Генерация Сортируемых Guid с Помощью NewId. Окончание
Начало
NewId вместо полностью случайных Guid предоставляет UUID, который можно легко отсортировать. Рассмотрим простое приложение:
using MassTransit;
foreach (var i in Enumerable.Range(0, 5))
{
NewId id = NewId.Next();
Console.WriteLine(id);
}
Эта программа генерирует 5 идентификаторов. В результате получается что-то вроде этого:
be170000-f32d-18db-de59-08da26f2ad5a
be170000-f32d-18db-1816-08da26f2ad5b
be170000-f32d-18db-8694-08da26f2ad5b
be170000-f32d-18db-4dbd-08da26f2ad5b
be170000-f32d-18db-65b3-08da26f2ad5c
На первый взгляд может показаться, что все они одинаковы, но давайте разобьём первый экземпляр на 3 части:
- be170000-f32d-18db — очевидно, это постоянное значение для всех идентификаторов.
- de59 — меняется с каждым ID.
- 08da26f2ad5a — иногда меняется, и меняется постепенно.
NewId использует 3 разных источника для создания идентификатора:
1. ID машины/процесса – константа для данной машины (может быть настроена для включения идентификатора процесса).
2. Временную метку - обеспечивает базовый порядок идентификатора.
3. Последовательность - увеличивающийся идентификатор.
Объединив все 3 вместе, вы можете получить идентификатор, который (с натяжкой) упорядочен благодаря компоненту метки времени. Включив идентификатор рабочего процесса, вы можете заставить процессы генерировать независимые ID, избегая при этом коллизий. Это можно сделать, например, вызвав в начале программы:
NewId.SetProcessIdProvider(new CurrentProcessIdProvider());
А использование «последовательности» означает, что вы можете генерировать 2^16-1 идентификаторов в миллисекунду для каждого процесса/машины.
Очевидно, что такие ID приводят к гораздо менее фрагментированному индексу базы данных. Конечно, с идеально последовательными целыми числами они не сравнятся. Но сравнение индексов в оригинальной статье показало, что полностью случайные Guid приводят к почти 99% фрагментации индекса, тогда как фрагментация индекса NewId составляет лишь 5%.
Сгенерированные идентификаторы предсказуемы по своей сути. Их не следует использовать в сценариях, где желательна непредсказуемость. Эти идентификаторы НЕ должны использоваться для:
- генерации паролей,
- токенов безопасности
- ничего другого, когда нежелательно угадывание значения.
Идентификаторы, сгенерированные NewId, раскрывают личность машины, сгенерировавшей идентификатор (фактически, это её MAC-адрес), и время, когда она это сделала. Это может быть проблемой для некоторых чувствительных к безопасности приложений.
Источник: https://andrewlock.net/generating-sortable-guids-using-newid/