Кратко

  • UUIDv7 начинается с 48-битного времени Unix в миллисекундах. Остальные 74 доступных бита по умолчанию случайны либо содержат необязательную долю миллисекунды и счётчик.
  • Порядок внутри миллисекунды, откат часов, переполнение счётчика и постоянное состояние определяет реализация. Сортировка значений независимых узлов не доказывает причинный или транзакционный порядок.
  • UUID служит идентификатором, а не аутентификацией, разрешением или носителем полномочий. Системе нужны отдельные поля времени события, генератора, причинной ссылки, позиции фиксации и проверяемой квитанции.

Первые 48 бит обслуживают индекс

UUIDv4 распределяет новые ключи случайно. Это удобно для децентрализованной генерации, но последовательные вставки могут попадать в далёкие страницы индекса. RFC 9562 ввёл упорядоченные по времени форматы, чтобы улучшить локальность и позволить сравнивать UUID как непрозрачные байты.

В UUIDv7 старшие 48 бит содержат миллисекунды с эпохи Unix без високосных секунд. Далее расположены версия и вариант. Остаются 74 бита для случайных данных либо разрешённого сочетания дополнительной точности, счётчика и случайности. Документ рекомендует выбирать v7 вместо v1 или v6, когда это возможно.

В обычном случае значение из более поздней миллисекунды сортируется после раннего. Близкие вставки группируются. Это реальная и проверяемая польза.

Однако время принадлежит часам и политике генератора. Оно не выдано общим секвенсором транзакций, удостоверяющей время стороной или причинным графом. Видимость времени не повышает авторитет его источника.

Внутри миллисекунды допустимы разные порядки

Быстрый сервис создаёт много UUID с одинаковым временным префиксом. Хорошие случайные окончания снижают вероятность столкновения, но их величина необязательно повторяет порядок создания.

RFC 9562 описывает три необязательных метода монотонности: фиксированный счётчик в старших доступных битах, монотонный счётчик со случайным началом или до 12 бит дополнительной точности времени. Остаток можно сохранить случайным.

Две соответствующие стандарту библиотеки вправе выбрать разные способы. Два процесса на одном хосте могут иметь независимые счётчики. После объединения байтовая сортировка создаёт полный порядок, но он не обязан совпасть с началом, завершением, фиксацией или публикацией операций.

Уникальность и порядок — разные обещания. Энтропия уменьшает столкновения. Счётчик упорядочивает один генератор. Ни одно средство не создаёт причинность между независимыми писателями.

При движении часов назад меняется смысл

Ручная коррекция, синхронизация, восстановление виртуальной машины или сбой могут вернуть часы назад. RFC 9562 оставляет реализациям выбор поведения, соответствующего требованиям.

Система, которой нужна монотонность, должна сравнивать новый UUID с предыдущим. Если он не больше, можно сохранить старый timestamp и увеличить счётчик, подождать физические часы, продвинуть встроенное время вперёд либо сообщить ошибку.

Каждый вариант меняет свидетельство. Сохранение прошлого времени защищает локальный порядок, но отдаляет число от настоящего. Ожидание стоит доступности. Продвижение сознательно пишет будущее. Ошибка отказывается выдавать идентификатор.

Спецификация также разрешает изменять, размывать или сглаживать timestamp и не гарантирует его близость к фактическому времени. Декодирование первых битов не раскрывает применённую политику. Её нужно записывать отдельно.

Граница состояния определяет границу гарантии

Генератор может хранить последний timestamp, счётчик и случайное состояние в устойчивом хранилище. После перезапуска это помогает продолжить выше старых значений. Постоянное состояние необязательно; разрешено начать как новую партию, увеличив риск столкновения и нагрузку на источник энтропии.

Обещание монотонности должно назвать область: поток, процесс, хост, кластер или регион. Счётчик в памяти контейнера не упорядочивает соседний контейнер. RFC отмечает, что монолитная база может получить лучшую монотонность, самостоятельно создавая UUID.

Распределённые узлы генерируют независимо. Случайность защищает от повторов, но не предоставляет общего секвенсора. Слияние и сортировка удобны для страниц и приблизительной хронологии, однако не создают задним числом порядок фиксации.

Синхронизация времени не выражает причины

NTP и практика RFC 8633 улучшают качество часов. Они не обещают полного совпадения прикладных часов в каждую секунду и не описывают зависимость одного действия от другого.

Если сервис A записал данные и послал сообщение B, разница часов может поставить UUID B раньше UUID A. Повторная попытка получит идентификатор на другом этапе. В одной миллисекунде два узла могут использовать разные окончания.

Причинное доказательство приходит из приложения: B ссылается на сообщение A, база выдаёт позицию commit, журнал выпускает квитанцию после принятия. Эти данные сосуществуют с UUIDv7. UUID даёт ключ и временную подсказку; ссылка или последовательность несёт более сильное утверждение.

Это не сообщение о недостатке стандарта. RFC 9562 определяет идентификаторы и методы генерации, а не распределённый консенсус или мировые часы.

Удобная сортировка не должна стать показанием аудита

Хранилище сортирует по UUID и называет результат «порядком событий». Такое название предполагает сопоставимые часы, одинаковую политику отката, совместимые методы внутри миллисекунды, генерацию в правильной точке жизненного цикла и отсутствие предварительной выдачи, повторов или исторического импорта.

Любое предположение способно нарушиться при полностью корректном UUID. Ключ может появиться перед транзакцией, которая затем откатится, до доставки очереди или сегодня для старой записи. Разрешённое размытие времени тоже меняет близость к реальности.

Проверяемая схема разделяет неизменный ID; время события и источник; время приёма; генератор и версию политики; причинного предшественника; последовательность commit или квитанции. Не всякой системе нужны все поля, но она должна назвать требуемое доказательство.

Если остался лишь UUIDv7, допустимо говорить о приблизительном порядке по часам генератора. Разрешать спор о том, кто действовал первым, только по нему нельзя.

Идентификатор не даёт права доступа

RFC 9562 предупреждает, что UUID не следует считать трудными для угадывания, и запрещает использовать их как возможности безопасности, где владение открывает ресурс. Хорошие случайные биты v7 не отменяют границу.

Стойкость к столкновениям, непредсказуемость и полномочие различаются. Энтропия и CSPRNG улучшают первые свойства, но не удостоверяют предъявителя и не разрешают операцию.

Встроенное время может раскрывать порядок создания, а счётчик — темп. RFC 4086 и RFC 8937 показывают, почему случайный вид не равен безопасности.

API должна аутентифицировать действующее лицо, авторизовать действие и отдельно защищать целостность. Корректно записанный UUID не доказывает владение.

Проверять нужно конкретное обещание

Для локальности измеряют реальную базу и индекс. Для локальной монотонной пагинации документируют область генератора, метод миллисекунды, устойчивое состояние и реакцию на откат.

Для распределённого аудита записывают место выдачи, источник часов, версию политики и этап жизненного цикла. Причинную связь и позицию commit добавляют явно. Если на порядок полагаются третьи стороны, требуется проверяемая квитанция.

Испытания охватывают всплеск в одну миллисекунду, исчерпание счётчика, перезапуск, потерю состояния, скачки часов, разделение регионов и слияние потоков. Так UUIDv7 выполняет свою задачу, не изображая власть над историей.

Источники