🆔
Инструменты разработчика
May 21, 20268 min readBy BrowseryTools Team

UUID: что это такое и как их генерировать

Что такое UUID, чем отличаются версии UUID v1, v4, v5, когда использовать UUID вместо последовательных идентификаторов и как безопасно генерировать их в браузере.

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 →