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, когда люди или текстовые системы обрабатывают идентификаторы.
Эта страница переведена с английского автоматически. Если вы заметили ошибку, сообщите нам.