UUID v4: что это такое и когда его использовать
Практическое руководство по UUID v4 — как он работает, когда использовать как первичный ключ и чем отличается от других стратегий уникальных ID.
Уникальные идентификаторы нужны везде: строки в базах данных, API-ресурсы, токены сессий, имена загруженных файлов. UUID v4 — один из самых распространённых форматов. Он случаен, устойчив к коллизиям и стандартизирован. Разберём, что это такое, как работает и когда стоит (и не стоит) его применять.
Что такое UUID?
UUID расшифровывается как Universally Unique Identifier. Это 128-битное значение, записанное в виде 32-символьной шестнадцатеричной строки, разбитой на пять групп:
xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
Цифра 4 в третьей группе — маркер версии 4 (случайной). Символ y в четвёртой группе принимает одно из значений 8, 9, a или b — это маркер варианта. Всё остальное — случайные данные.
Типичный UUID выглядит так:
f47ac10b-58cc-4372-a567-0e02b2c3d479
Как генерируется UUID v4
UUID v4 строится из 122 бит случайности, оставшиеся 6 бит кодируют версию и вариант. Современные браузеры предоставляют crypto.randomUUID(), который использует криптографически стойкий генератор (CSPRNG) — результат безопасен даже для чувствительных контекстов вроде токенов сессий.
Вероятность коллизии ничтожно мала. Чтобы получить 50-процентный шанс хотя бы одной коллизии, нужно сгенерировать более 2,7 × 10¹⁸ UUID — это примерно 86 миллиардов в секунду на протяжении миллиарда лет.
Когда UUID v4 уместен
Первичные ключи в БД. UUID v4 хорошо подходит для распределённых систем, где несколько сервисов создают идентификаторы независимо. Никакого центрального счётчика, никаких блокировок — каждый узел генерирует и записывает самостоятельно.
Идентификаторы API-ресурсов. Последовательные числовые ID позволяют перебирать ресурсы простым инкрементом: /users/1, /users/2 и так далее. UUID это исключает.
ID корреляции и трассировки. Привязываете UUID к каждому входящему запросу и пишете его во все логи. Когда что-то ломается в трёх сервисах одновременно, находите все записи по этому ID и восстанавливаете цепочку событий.
Имена загруженных файлов. UUID как имя файла исключает коллизии и не раскрывает оригинальное имя в хранилище.
Токены сессий. UUID работает как токен сессии при наличии серверной проверки. Для очень высоких требований к безопасности лучше взять больше бит, но для большинства приложений этого достаточно.
UUID v4 в сравнении с другими подходами
| Стратегия | Случайный? | Сортируемый? | Короткий? |
|---|---|---|---|
| UUID v4 | Да | Нет | Нет |
| UUID v1 | Нет (временной) | Да | Нет |
| ULID | Да | Да | Нет |
| Nano ID | Да | Нет | Да |
| Автоинкремент | Нет | Да | Да |
Если нужны упорядоченные по времени ID — удобно для индексов БД и пагинации — смотрите на ULID или UUID v7 со встроенной временной меткой. Для коротких ID в URL обычно берут nanoid. Для одного сервера без требований к распределённости целочисленный автоинкремент по-прежнему вполне разумный выбор.
UUID v4 в базах данных
Несколько вещей, которые стоит знать, прежде чем ставить UUID первичным ключом.
Фрагментация индекса. B-дерево работает лучше всего при последовательных вставках. Случайные UUID разбрасывают записи по всему индексу, что снижает производительность записи при большом объёме данных. gen_random_uuid() в PostgreSQL и UUID_TO_BIN(..., 1) в MySQL 8 частично решают проблему — второй вариант переупорядочивает байты, делая UUID частично последовательным. UUID v7 решает это чище.
Объём хранения. UUID в виде CHAR(36) занимает больше места, чем 4-байтовое целое. Используйте нативный тип UUID в PostgreSQL и MySQL 8 или BINARY(16) в остальных случаях.
Читаемость при отладке. Таблицы с UUID-ключами сложнее проверять вручную: глядя на результат запроса, невозможно понять, что перед тобой. Иногда рядом с UUID стоит держать короткий человекочитаемый slug — лишнее поле, но экономит время при отладке.
Нужен UUID прямо сейчас? Генератор UUID работает полностью в браузере — без регистрации и установки. Укажите количество, при желании включите верхний регистр и скопируйте всё сразу.