Объяснение версий UUID — прекращайте использовать v4 во всём
UUID v4 является стандартным по умолчанию во всём, но он разбивает индексы вашей базы данных. Вот в каких случаях использовать v4, v7 и ULID — и почему ваш DBA поблагодарит вас за переход.
Вашем коде есть строка, которая выглядит так: id = uuid.v4()Оно работает. Ваши тесты проходят. Пользователи никогда не жалуются. А ваш DBA тихо раздражается каждый раз, когда смотрит на план запроса.
UUID v4 стал стандартным по умолчанию, потому что он прост, доступен во всём мире и имеет достаточную устойчивость к коллизиям, чтобы вы никогда не столкнулись с конфликтом. Но «оно работает» и «это правильный инструмент» — это не одно и то же, и для первичных ключей в базе данных v4 фактически замедляет систему при масштабировании.
Что делает UUID v4 с вашей базой данных
Реляционные базы данных используют B-деревья для первичных ключей. B-дерево сохраняет данные в порядке, чтобы база данных могла находить строки за O(log n) времени. При вставке новой строки база данных должна разместить её в правильном упорядоченном положении в индексе.
С UUID v4 каждая новая идентификатор является случайной. 550e8400-e29b-41d4-a716-446655440000 может быть за ним следующий f47ac10b-58cc-4372-a567-0e02b2c3d479 — между последовательными вставками нет связи. База данных должна каждый раз перемещаться к случайной листовой вершине в B-дереве.
Это вызывает две проблемы при масштабировании:
- Разделение страниц: Когда листовая страница B-дерева заполняется, база данных должна разделить её на две страницы и обновить родительскую. При случайных вставках разделения происходят часто по всей индексу — не только в конце.
- Проблемы с кэшем: База данных хранит в памяти недавно используемые страницы. Последовательные вставки постоянно обращаются к одной и той же «горячей» странице. Случайные вставки рассеивают чтения по всей индексу, что приводит к перегрузке кэша и вынуждает обращаться к диску.
На таблице с миллионами строк и высокой скоростью записи это разрушение индекса приводит к реальной задержке. Если EXPLAIN ANALYZE показывает, что сканирование индекса занимает больше времени, чем нужно, случайные UUID могут быть частью диагностики.
Дерево UUID
UUID v1: Временные метки, MAC-адреса и то, почему мы не используем его
UUID v1 был первоначальным «упорядоченным» UUID. Он кодирует 60-битную временну метку в интервалах 100-наносекунд с 15 октября 1582 года, вместе с последовательностью часов и MAC-адресом вашей машины. Результат — приблизительно упорядоченный по времени.
Часть MAC-адреса убила v1. Он утечку идентификатора сетевого интерфейса в каждый идентификатор, который вы генерируете — в каждую запись пользователя, каждый заказ, каждый событие. Исследователи продемонстрировали, что UUID v1 с одного и того же устройства предсказуемы, если у вас есть один образец. Организации начали избегать его для любых пользовательских функций, и большинство библиотек UUID помечены как устаревшие.
UUID v4: Случайный, безопасный и не подходит для первичных ключей
UUID v4 — это 122 бита криптографически случайных данных (оставшиеся биты кодируют версию). Вероятность коллизии для миллиарда UUID составляет примерно 1 из 10^18. На практике это ноль.
Эта случайность — именно то, что вам нужно для безопасных токенов, идентификаторов сессий, API-ключей и корреляционных идентификаторов — любых случаев, где вам нужен идентификатор, который не может быть угадан или перечислен. Для этих случаев продолжайте использовать v4. Проблема в том, что «не может быть угадан» и «для базы данных удобно» — это противоположные свойства.
Хотите протестировать генерацию UUID? На UUID Generator на IO Tools вы можете генерировать v1, v4, v7 и другие варианты одновременно, чтобы увидеть различия в структуре.
UUID v7: Новый стандарт, который вы должны использовать
UUID v7 был стандартизирован IETF в RFC 9562 в мае 2023 года. В нём помещается временная метка в миллисекундах в 48 значащих битах, за которой следует 4-битное поле версии, 12-битный счётчик последовательности и 62 бита случайных данных.
Практически это означает: UUIDs, генерируемые позже, являются лексикографически большими. Последовательные вставки попадают в соседние позиции в B-дереве. Нет случайного рассеивания, нет лишних разделений страниц, нет перегрузки кэша. Оно ведёт себя так, как если бы это было целое число с авто-увеличением из базы данных — при этом остаётся глобально уникальным без координации.
Счётчик последовательности в пределах одного миллисекунды обеспечивает монотонное упорядочение даже при высокой частоте генерации. Если вы генерируете 10 000 UUID в течение одного миллисекунды, они всё равно будут правильно отсортированы. Случайный суффикс сохраняет достаточно энтропии, чтобы вероятность коллизий между распределёнными системами оставалась астрономически низкой.
Для любого нового проекта, использующего PostgreSQL, MySQL или другую реляционную базу данных, UUID v7 должен быть стандартом для первичных ключей.
ULID: Альтернатива, которая появилась раньше
ULID (Universally Unique Lexicographically Sortable Identifier) решал ту же проблему, до того как появился UUID v7. Он использует 48 бит для временной метки в миллисекундах и 80 бит случайных данных, закодированных в Crockford's Base32.
Результат — это строка из 26 символов, которая выглядит так: 01ARZ3NDEKTSV4RRFFQ69G5FAV вместо стандартного формата из 36 символов с дефисами. Он безопасен для URL без кодирования, правильно сортируется как строка и не чувствителен к регистру.
ULID не имеет IETF RFC — у него есть сообщество спецификации на ulid.github.io. Это достаточно для большинства команд, но если вы работаете в регулируемой среде, где требуется формально стандартизированные идентификаторы, UUID v7 — более безопасный выбор. ULID имеет сильную поддержку в экосистемах JavaScript и Go, и если ваша команда уже использует его, нет срочной необходимости переключаться.
Сравнение бок о бок
| Свойство | UUID v1 | Уникальный идентификатор версии 4 | UUID v7 | УЛИД |
|---|---|---|---|---|
| Сортируемый | Частично | Нет | Да | Да |
| Устойчив к коллизиям | Да | Да | Да | Да |
| Для базы данных удобен | Частично | Нет | Да | Да |
| Безопасен с точки зрения конфиденциальности | Нет (MAC addr) | Да | Да | Да |
| Стандартный орган | IETF RFC 4122 | IETF RFC 4122 | IETF RFC 9562 | Спецификация сообщества |
| Обычный размер | 36 символов | 36 символов | 36 символов | 26 символов |
| Источник энтропии | MAC + часы | Случайный | Временная метка + случайные данные | Временная метка + случайные данные |
Когда использовать каждый из них
UUID v7 — используйте это для первичных ключей в любой новой системе. Это стандарт IETF, имеет растущую поддержку библиотек (встроен в PostgreSQL 17, доступен через библиотеки в каждой из основных языков), и даёт упорядоченную сортировку в B-дереве без необходимости координации.
Уникальный идентификатор версии 4 — продолжайте использовать это для любых случаев, где важна случайность: токены сессий, токены восстановления пароля, API-ключи, параметры OAuth, корреляционные идентификаторы в логах. Непредсказуемость — это преимущество, а не недостаток.
УЛИД — используйте его, если ваша команда уже использует его, особенно в проектах на JavaScript или Go. Короткая форма действительно лучше в URL и логах. Если вы начинаете с нуля, UUID v7 — более безопасный долгосрочный выбор, потому что он имеет поддержку IETF.
UUID v1 — не используйте. Нет ни одной ситуации, в которой v1 является правильным выбором для нового кода.
Рассмотрение миграции
Если у вас уже есть система с первичными ключами UUID v4, вам не нужно немедленно мигрировать — и вы не должны делать это бездумно. Внешние ключи, код приложения и потенциально кэшированные значения все ссылается на эти идентификаторы. Миграция требует тщательного планирования и, скорее всего, технического окна обслуживания.
Для большинства команд практический подход заключается в том, чтобы использовать UUID v7 (или ULID) для всех новых таблиц и сервисов. Принимайте, что ваши устаревшие таблицы имеют v4, и управляйте разрушением индекса периодическими перестройками, если влияние на производительность измеримо. Не позволяйте идеалом быть врагом хорошего.
Если вы работаете над новым проектом, новой базой данных и новыми таблицами — нет причин использовать v4 для первичных ключей. Инструменты уже есть. Сгенерируйте несколько образцов UUID v7 и посмотрите, что вы получаете.
Выводы
UUID v4 не ошибочен — он просто часто неправильно применяется. Его случайность — это свойство безопасности, и вы должны сохранять его там, где безопасность важна. Для первичных ключей в базе данных эта случайность превращается в проблему производительности при масштабировании.
UUID v7 решает проблему чисто: монотонно увеличивающийся, глобально уникальный, стандартизированный и уже поддерживаемый в базах данных и ORM-библиотеках, которые вы используете. Если вы пишете схемы базы данных сегодня, сделайте v7 вашим стандартом. Будущий вас — и ваш DBA — заметят разницу.
Установите наши расширения
Добавьте инструменты ввода-вывода в свой любимый браузер для мгновенного доступа и более быстрого поиска
恵 Табло результатов прибыло!
Табло результатов — это интересный способ следить за вашими играми, все данные хранятся в вашем браузере. Скоро появятся новые функции!
Подписаться на новости
все Новые поступления
всеОбновлять: Наш последний инструмент was added on Июн 22, 2026
