Utilo

UUID v4 vs UUID v7 vs ULID: какой уникальный идентификатор следует использовать?

Сравните случайный UUID v4, UUID v7 с временным порядком и ULID для ключей базы данных, API и распределенных систем с компромиссами производительности, конфиденциальности и формата.

· 5 мин чтения

Автоувеличивающие целые числа были основным ключом по умолчанию в течение десятилетий. Они компактные и быстрые, но требуют централизованной базы данных для распределения номеров, утечки информации о количестве записей, и объединения данных из нескольких систем. Глобально уникальные идентификаторы решают эти проблемы: любой сервер, мобильное приложение или офлайн-клиент может создать идентификатор, который никогда не столкнется. Вопрос в том, какой. В этом руководстве сравниваются три наиболее популярных варианта UUID в 2026 году: UUID версия 4, UUID версия 7 и ULID.

Быстрое обновление UUID

UUID (Universally Unique Identifier) - это 128-битное значение, обычно записываемое в виде 32 гексадецимальных цифр в пяти группах:

550e8400-e29b-41d4-a716-446655440000

Нынешний стандарт, RFC 9562 (опубликованный в 2024 году, заменяющий RFC 4122), определяет несколько версий. Несколько бит кодируют версию и вариант; остальное зависит от версии. Третья группа всегда начинается с номера версии, так что вы можете отличить V4 от V7 на первый взгляд.

UUID v4: чисто случайный

UUID версии 4 содержит 122 случайных бита плюс 6 фиксированных битов для версии и варианта.

Сильные стороны

  • Тривиально генерировать: каждый язык и база данных имеет встроенную функцию, такую как crypto.randomUUID() в JavaScript или gen_random_uuid() в PostgreSQL.
  • Ничего не раскрывает: ни временной отметки, ни идентификатора машины, ни последовательности.
  • Вероятность столкновения незначительна. Вам нужно будет генерировать около 2,7 × 10^18 ID для 50% вероятности одного дубликата.

Слабые стороны

  • Случайный порядок вредит индексам баз данных. Индексы B-дерева, используемые PostgreSQL, MySQL и SQL Server, лучше всего работают, когда новые ключи поступают в возрастающем порядке. Случайные клавиши попадают по всему индексу, вызывая разделение страниц, плохую локализацию кэша и усиление записи. На больших таблицах объем вставки может значительно снизиться, а индексы вырастают больше, чем необходимо.
  • Не сортируется по времени создания, поэтому вам нужна отдельная колонка created_at для хронологических запросов.

UUID v7: в порядке времени

Версия 7 помещает 48-битную Unix временную метку в миллисекундах спереди, за которой следуют 74 бита случайности (некоторые реализации используют часть ее в качестве счетчика для упорядочения в течение той же миллисекунды).

01928c3e-5b7a-7c4d-9f3e-2a1b4c5d6e7f
└─timestamp─┘ └version 7

Сильные стороны

  • Новые идентификаторы примерно увеличиваются, поэтому вставки добавляются к концу индекса как клавиши автоматического увеличения. Так индексы сохраняются компактными и записываются быстро.
  • Сортировка по типам идентификаторов по времени создания, что делает курсорную pagination простой: WHERE id > :last_id ORDER BY id LIMIT 50.
  • Это по-прежнему стандартный UUID: он подходит для коренных столбцов uuid, ORM и API, которые уже принимают UUID.
  • Вы можете извлечь время создания из идентификатора для отладки.

Слабые стороны

  • Время создания видно каждому, кто видит идентификатор. Для большинства записей это безобидно; для некоторых, таких как учетные записи пользователей в продуктах, чувствительных к конфиденциальности, это может показать, когда кто-то подписался.
  • Требует довольно точных часов. Большие скачки часов назад могут производить идентификаторы, которые сортируются раньше, чем существующие; хорошие библиотеки справляются с этим с помощью монотонных счетчиков.
  • Функции генерирования новые. PostgreSQL 18 добавил uuidv7(); на старых версиях, генерировать в приложении код.

ULID: сортируемый и компактный текст

ULID (Universally Unique Lexicographically Sortable Identifier) предшествует UUID v7 и использует ту же идею: 48-битный миллисекундный временной штемпель, за которым следуют 80 случайных бит. Разница в текстовой форме: 26 символов Crockford Base32.

01J9Z3K8M2Q7X4V5B6N8P0R2T4

Сильные стороны

  • Более короткий, чем 36-знаковая строка UUID и URL-безопасный.
  • Он не чувствителен к большим и малым буквам и исключает двусмысленные буквы (I, L, O, U), поэтому легче читать вслух или печатать.
  • Лексикографическое сортирование строки равно хронологическому сортированию, которое помогает в системах, которые хранят идентификаторы в виде текста, таких как хранилища ключевых значений или имена файлов журналов.

Слабые стороны

  • Не UUID, поэтому он не подходит для коренных типов столбцов UUID без конверсии (хотя его 128 бит могут храниться в одном).
  • Спецификация сообщества, а не стандарт IETF, с немного другим поведением между библиотеками.
  • Как и V7, он раскрывает время сотворения.

Сопоставление со стороны

Недвижимость UUID v4 UUID v7 ULID
Размер 128 бит 128 бит 128 бит
Длина текста 36 36 26
Временное Нет , нет . Да , да . Да , да .
Утечка времени создания Нет , нет . Да (мс) Да (мс)
Стандартный RFC 9562 RFC 9562 Спецификация Сообщества
Тип DB uuid uuid Обычно текстовые или двоичные
Индексные вставки Бедные . Хорошо . Хорошо .

Советы по хранению

Что бы вы ни выбрали, храните идентификаторы в виде 16 байтов, а не текста. 36-значная строка занимает более чем вдвое больше места, и каждый индекс и иностранный ключ, ссылающийся на него, умножает стоимость. PostgreSQL имеет родный тип uuid; пользователи MySQL могут использовать BINARY(16) с UUID_TO_BIN(uuid, 1), где второй аргумент переупорядочивает временные знаки v1 для v7 используют по умолчанию, поскольку он уже упорядочен по времени.

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

Отношения безопасности

Ни одно из этих удостоверений не является секретом. Не используйте их в качестве токенов для сброса пароля или идентификаторов сеанса только потому, что их трудно угадать. UUID v4 имеет достаточное количество случайности, чтобы быть неиспытываемым, но v7 и ULID имеют предсказуемые префиксы временных меток, которые уменьшают эффективную энтропию. Для секретов, генерируйте по крайней мере 128 случайных битов с помощью криптографического генератора и обращайтесь с ними как с паролями, в идеале хранить только хэш см. MD5 vs SHA-256 для использования хэша.

Рассмотрим также перечисление. Последовательные целые числа позволяют любому угадать /orders/1001, /orders/1002. Случайные или временные идентификаторы делают это непрактичным, но они не могут заменить проверку разрешения на каждый запрос.

Какой из них выбрать?

  • Основные ключи базы данных в новой системе: UUID v7. Вы получаете распределенное производство и хорошую производительность индекса с полной совместимостью UUID.
  • Общественные идентификаторы, когда время создания должно оставаться частным: UUID v4, или внутренний ключ v7 в сочетании с отдельным случайным общественным идентификатором.
  • Для текстовых хранилищ, имен файлов или идентификаторов люди могут ввести: ULID, для его более короткой, нечувствительной к большим и малым буквам формы.
  • Существующая система на v4 с проблемами производительности: рассматривать v7 для новых таблиц; смешивание версий в одном столбце технически нормально, потому что оба являются действительными UUID.

Создание идентификаторов

Для быстрых задач семенные данные, тестовые приборы, ручные вставки браузерный [генератор UUID] ((/tools/uuid) может производить до 1000 значений v4, v7 или ULID одновременно с использованием crypto.getRandomValues. В коде приложения используйте стандартную библиотеку вашего языка или хорошо поддерживаемый пакет и генерируйте идентификаторы, как можно ближе к созданию записей.

Итоги

UUID v4 случайный и частный, но рассеивает индексы баз данных. UUID v7 добавляет префикс временной метки, который обеспечивает быстрое вставку и сортировку идентификаторов при сохранении стандартного UUID. ULID предлагает тот же порядок с более коротким, более дружественным текстовым форматом. Для большинства новых приложений UUID v7 является лучшим по умолчанию; выберите v4, когда время должно оставаться скрытым, и ULID, когда люди или текстовые системы обрабатывают идентификаторы.

Эта страница переведена с английского автоматически. Если вы заметили ошибку, сообщите нам.

Похожие руководства