UUID: что это такое и как их генерировать
Что такое UUID, чем отличаются версии UUID v1, v4, v5, когда использовать UUID вместо последовательных идентификаторов и как безопасно генерировать их в браузере.
Каждая запись в базе данных, ресурс API, распределённое событие и токен сессии нуждаются в уникальном идентификаторе. Выбор формата ID важнее, чем может показаться — он влияет на безопасность, производительность базы данных, читаемость URL и поведение системы при горизонтальном масштабировании или объединении данных из разных источников. В этом руководстве рассматриваются основные варианты: UUID (v1, v4, v7), NanoID и CUID, а также когда применять каждый из них.
Вы можете мгновенно генерировать UUID и другие уникальные идентификаторы с помощью генератора UUID BrowseryTools — бесплатно, без регистрации, всё генерируется локально в браузере.
Почему автоинкрементных ID недостаточно
Последовательные целочисленные ID (1, 2, 3, ...) — это стандарт в большинстве реляционных баз данных, и они хорошо работают для простых односерверных приложений. Однако при масштабировании или в распределённых системах они создают проблемы:
- Предсказуемость — зная один ID, легко угадать другие.
/orders/1042сразу говорит о существовании заказа 1041 и о масштабе вашего бизнеса. Это уязвимость IDOR (небезопасная прямая ссылка на объект), если авторизация не реализована на уровне приложения. - Конфликты при слиянии — при объединении данных из двух баз данных две разные последовательности автоинкремента дадут коллизии ID. Многотенантные системы, офлайн-приложения и миграции сталкиваются с этой проблемой.
- Распределённая генерация — когда несколько серверов или воркеров вставляют записи, нужен механизм координации (единая последовательность или последовательность на уровне СУБД), чтобы избежать дублирующихся ID. Это создаёт узкое место.
- Утечка бизнес-метрик — последовательные ID раскрывают конкурентам объём заказов, количество пользователей и темп роста.
Что такое UUID?
UUID (Universally Unique Identifier, также называемый GUID) — это 128-битное число, традиционно отображаемое в виде 32 шестнадцатеричных цифр в пяти группах, разделённых дефисами:
xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx
Пример: 550e8400-e29b-41d4-a716-446655440000
^ ^ ^ ^ ^
| | | | 12 hex-цифр (48 бит)
| | | биты варианта (N)
| | цифра версии (M)
| 4 hex-цифры
8 hex-цифрЦифра версии (M) указывает, какой алгоритм генерации UUID использовался. Биты варианта (N) всегда равны 8, 9, a или b в стандартных UUID. Оставшиеся 122 бита доступны для самих данных идентификатора.
UUID v1: MAC-адрес + временная метка
UUID v1 объединяет текущую временную метку (в 100-наносекундных интервалах с 15 октября 1582 года), MAC-адрес генерирующей машины и последовательность часов для обработки быстрой генерации. Результат теоретически уникален для всех машин и времён.
Проблема в том, что UUID v1 раскрывает и когда, и где он был сгенерирован — MAC-адрес виден в открытом виде. Это проблема конфиденциальности, и она была использована в черве Melissa (1999) для отслеживания заражённых документов до конкретных машин. По этой причине v1 редко используется в новых приложениях. Большинство разработчиков, которым нужны временно-упорядоченные ID, обращаются к v7.
UUID v4: случайный
UUID v4 — самый широко используемый вариант. Он состоит из 122 бит криптографически случайных данных (оставшиеся 6 бит кодируют версию и вариант). Никакой временной метки, никакого MAC-адреса, никакой последовательной составляющей — только энтропия.
// Node.js 14.17+
const { randomUUID } = require('crypto');
randomUUID(); // → "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d"
// Браузер
crypto.randomUUID(); // → "1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed"
// Python
import uuid
str(uuid.uuid4()) # → "3d6f4580-2b3e-44e4-9d40-2d0ab12b4e7e"Насколько маловероятны коллизии UUID v4?
При 122 битах случайности вероятность коллизии ничтожно мала. Чтобы вероятность хотя бы одной коллизии достигла 50%, потребовалось бы сгенерировать приблизительно 2,7 × 1018 UUID — это 2,7 квинтиллиона. Если генерировать миллиард UUID в секунду, на это ушло бы около 85 лет. Для любого реального приложения коллизии не являются практической проблемой. Гораздо более вероятный источник дублирующихся ID — баги приложения (ошибки копирования, попадание в кэш старых ID и т. д.), а не сам генератор.
UUID v7: случайный с временным порядком
UUID v7 был стандартизирован в RFC 9562 (2024) для устранения главного практического недостатка v4: случайные UUID — плохие первичные ключи для баз данных, поскольку они разрушают локальность индекса. При вставке записей со случайными ID каждая вставка попадает в случайную позицию B-дерева, вызывая разделения страниц, промахи кэша и фрагментацию при масштабировании.
UUID v7 встраивает временну́ю метку Unix с миллисекундной точностью в старшие биты, после которых идут случайные данные. Это означает, что UUID v7 сортируемы — записи, вставленные в хронологическом порядке, имеют лексикографически возрастающие ID — при этом оставаясь глобально уникальными и непредсказуемыми за пределами границы миллисекунды:
Структура UUID v7: [48 бит: Unix-метка в мс][4 бита: версия=7][12 бит: случайные][2 бита: вариант][62 бита: случайные] Три UUID v7, сгенерированных последовательно: 0192fe2c-4b3a-7000-8000-0a1b2c3d4e5f ← самый ранний 0192fe2c-4b3b-7001-8000-0a1b2c3d4e60 ← чуть позже 0192fe2c-4b3c-7002-8000-0a1b2c3d4e61 ← самый поздний ^^^^^^^^^^ временно́й префикс монотонно возрастает
Если вы создаёте новое приложение, использующее UUID в качестве первичных ключей в реляционной базе данных, v7 — правильный выбор по умолчанию начиная с 2024 года.
NanoID: короче и безопасен для URL
NanoID — это не UUID, а совершенно другой формат ID, решающий ту же задачу. По умолчанию генерирует 21-символьную строку, используя URL-безопасный алфавит (A-Za-z0-9_-). Это даёт 126 бит энтропии — сопоставимо с UUID v4 — в строке из 21 символа вместо 36. Строки NanoID удобны для URL без дополнительного кодирования и выглядят чище в логах и URL для пользователей:
UUID v4: 9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d (36 символов)
NanoID: V1StGXR8_Z5jdHi6B-myT (21 символ)
import { nanoid } from 'nanoid';
nanoid(); // → "V1StGXR8_Z5jdHi6B-myT"
nanoid(10); // → "IRFa-VaY2b" (настраиваемая длина)NanoID популярен для коротких ссылок, токенов сессий, инвайт-кодов и любых случаев, когда ID фигурирует в URL и желательна компактность.
CUID2: сортируемый, без цифрового отпечатка
CUID2 (преемник CUID) разработан специально для использования в качестве первичных ключей базы данных. Генерирует 24-символьную строку, сортируемую по времени создания, без использования MAC-адреса или цифрового отпечатка, и сложнее поддаётся предсказанию, чем ID на основе временны́х меток. CUID2 использует SHA-3 внутри для смешивания временно́й метки со случайными данными, что делает вывод непредсказуемым даже при генерации в одну миллисекунду.
CUID2 — хороший выбор, когда вам нужны сортируемые ID, вы хотите избежать формата UUID полностью и вам важна непрозрачность ID (чтобы он не раскрывал информацию о временно́й метке напрямую).
Выбор правильного формата
- Первичный ключ базы данных, новый проект — UUID v7 или CUID2. Оба сортируемы, что сохраняет производительность индекса по мере роста данных.
- Универсальный уникальный ID, совместимость — UUID v4. Каждый язык и фреймворк понимает формат UUID нативно.
- Короткие ссылки, инвайт-коды, URL-токены — NanoID. Компактный, URL-безопасный, настраиваемая длина.
- Распределённые системы с генерацией ID на стороне клиента — UUID v4 или v7. Координация не нужна; клиенты генерируют свои ID до отправки на сервер.
- Избегайте v1 — он раскрывает ваш MAC-адрес. Ни один новый проект не должен его использовать.
Производительность UUID в качестве первичного ключа
Классическое предупреждение «не используйте UUID в качестве первичных ключей» относится именно к случайным UUID (v4) в MySQL с InnoDB или в любой базе данных, кластеризующей данные по первичному ключу. Случайный порядок вставки фрагментирует кластеризованный индекс. В PostgreSQL с некластеризованным UUID-индексом потери меньше, но при больших объёмах всё равно реальны. Практическое решение: используйте UUID v7 или CUID2 (которые монотонно возрастают), и проблема фрагментации в значительной мере исчезает. Используйте генератор UUID BrowseryTools для генерации UUID v7 при тестировании схемы перед выбором формата.
Бесплатный генератор UUID — v1, v4, v7, NanoID, CUID2
Открыть генератор UUID →Try the Tools — 100% Free, No Sign-Up
Everything runs in your browser. No uploads. No accounts. No ads.
Explore All Tools →