Изменить два байта в GUID - PullRequest
2 голосов
/ 18 марта 2019

Я использую разделенный CosmosDb, но я не знаю значения ключа раздела каждый раз, когда хочу получить ресурс по его идентификатору. Теперь использование идентификатора в качестве ключа раздела не является для меня решением, так как это заняло бы слишком много времени и заняло бы слишком много места (я слышал, что максимальное число ключей разбиения - 10 ГБ, но у меня их гораздо больше).

Моя идея состоит в том, чтобы манипулировать 2 байтами GUID, чтобы отобразить значение ключа моего раздела для каждой guid. Таким образом, мне не нужно использовать перекрестный запрос, а легко получить значение ключа раздела из моего GUID. Есть ли в GUID зарезервированные байты, которые я не могу изменить? Есть ли лучшие практики для этой проблемы?

1 Ответ

2 голосов
/ 18 марта 2019

В GUID есть компонент, основанный на времени, который вы можете изменить, и если вы понимаете последствия, это не приведет к коллизии.Вы можете прочитать о некоторых мыслях здесь:

https://blog.stephencleary.com/2010/11/few-words-on-guids.html

Соответствующий раздел гласит:

Основанные на времени GUID (Версия 1) Основанные на времени GUID являютсяВариант 2, Версия 1 RFC 4122 GUID, также известный как «последовательные GUID», потому что они могут быть сгенерированы со значениями, очень близкими друг к другу.Они состоят из трех полей в дополнение к варианту и версии: 60-битная метка времени UTC, 14-битная тактовая последовательность и 48-битный идентификатор узла.

Идентификатор узла обычно является MAC-адресомкомпьютер генерирует основанный на времени GUID (который гарантированно будет уникальным, поскольку MAC-адреса используют систему регистрации).Однако это также может быть 47-битное случайное значение (с установленным широковещательным битом).В этом случае нет опасности столкновения с реальными MAC-адресами, поскольку широковещательный бит физического MAC-адреса всегда равен 0. Однако существует опасность столкновения с другими случайными идентификаторами узлов;в частности, существует вероятность 50% коллизий, если в сеть войдут 13,97 млн. случайных узлов.

Примечание. Использование случайного значения вместо MAC-адреса в настоящее время не поддерживается Microsoft Win32 API от Microsoft.Это означает, что любое генерирование GUID, выполненное с использованием UuidCreateSequential, будет выставлять MAC-адрес.

Поле Clock Sequence инициализируется случайным значением и увеличивается всякий раз, когда системные часы перемещаются назад после последнего сгенерированного GUID (например, есликомпьютер корректирует свое время с помощью сервера времени, или если он потерял свою дату и считает, что это 1980).Это позволяет сбросить 16 384 часов без какой-либо опасности столкновения.Если GUID генерируются так быстро, что системные часы не сдвинулись вперед со времени последней метки времени GUID, тогда алгоритм генерации GUID обычно останавливается до тех пор, пока системные часы не увеличивают время.

Последовательные GUID на самом деле не являются последовательными,В обычных условиях идентификаторы GUID, генерируемые одним и тем же компьютером, будут постепенно увеличивать поля меток времени (при этом остальные поля будут оставаться постоянными).Однако поле Timestamp находится не в младших значащих битовых позициях GUID, поэтому, если GUID рассматривается как 128-битное число, оно фактически не увеличивается.

Важно отметить, что вероятностьколлизий последовательных идентификаторов GUID чрезвычайно мала.Последовательность часов и метка времени почти наверняка уникально идентифицируют момент времени, а идентификатор узла почти наверняка идентифицирует уникальный источник.

Последовательные GUID могут быть созданы с помощью функции Win32 UuidCreateSequential или с помощью uuidgen.exe из WindowsSDK, передающий параметр -x.

Вы также можете просмотреть соответствующую спецификацию здесь:

https://tools.ietf.org/html/rfc4122#section-4.1.1

...