Что такое UUID
UUID (Universally Unique Identifier) — 128-битный идентификатор, гарантированно уникальный без центральной координации. Записывается как 32 hex-символа с 4 дефисами: xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx. Где M — это цифра версии (1, 4, 7), N — вариант (обычно 8 или 9).
Главная польза UUID: распределённая генерация. В микросервисах каждый сервис может создавать свои ID без обращения к центральному генератору. Для 100 миллионов сгенерированных UUID v4 вероятность коллизии — 2.7×10⁻¹⁹ (близко к попаданию метеорита).
v4 vs v7 детально
UUID v4 — полностью случайный
Структура UUID v4:
xxxxxxxx-xxxx-4xxx-Yxxx-xxxxxxxxxxxx
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
6 бит зарезервированы под версию (4) и вариант (Y=8/9/A/B)
122 бита случайные
Пример:
f47ac10b-58cc-4372-a567-0e02b2c3d479
Особенности:
✅ Простой алгоритм: crypto.randomBytes(16) с заменой нескольких бит
✅ Безопасный: невозможно угадать
❌ Не сортируется: записи в БД попадают в случайные страницы B-tree
❌ Раскрывает только версию (4)UUID v7 — timestamp + random
Структура UUID v7:
xxxxxxxx-xxxx-7xxx-Yxxx-xxxxxxxxxxxx
^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^
| |
48 бит = Unix timestamp (мс)
12 бит подверсии
62 бита случайные
Пример:
018f7a8c-5d4e-7c2a-9f1b-3a5c7e9d2b4f
^^^^^^^^^^^^^
|
= 2024-05-15 14:23:11.234 UTC (ms)
Особенности:
✅ Сортируется по времени: ORDER BY id ≈ ORDER BY created_at
✅ Оптимизирован для B-tree: новые записи в одну страницу
✅ Совместим с UUID v4 (тот же формат хранения)
✅ ~62 бита энтропии — достаточно для уникальности
⚠️ Раскрывает время создания (приватность)UUID Version 7 features a time-ordered value field derived from the widely implemented and well-known Unix Epoch timestamp source. The UUIDv7 layout is intended for cases where it is desirable for UUIDs to be ordered and the order to relate to time of creation.— RFC 9562 — Universally Unique IDentifiers (UUIDs), May 2024
Производительность в БД
Замеры (PostgreSQL 16, миллион INSERT в таблицу с UUID primary key):
UUID v7 на 35% быстрее v4. Размер индекса на 25% меньше. Для большой таблицы (миллиарды записей) разница огромная: v7 даёт скорость близкую к bigint при сохранении всех преимуществ UUID (распределённая генерация, отсутствие коллизий).
Когда что использовать
UUID v7 — для:
- Primary key в БД. Лучшая производительность, особенно для часто-вставляемых таблиц.
- Event sourcing. События естественно упорядочены по времени.
- Логи и события мониторинга. Легко сортировать и querying по времени.
- Internal IDs между микросервисами. Если время создания не secret.
- Очереди сообщений. FIFO порядок без дополнительного timestamp.
UUID v4 — для:
- Public-facing IDs. URLs (/orders/uuid), API responses. Не раскрывает время.
- Session tokens. Невозможность угадать критична.
- API keys. 122 бита энтропии vs 62 у v7 — значительная разница для бруте.
- Криптографические nonces. Случайность приоритетнее сортируемости.
- Любые случаи где время создания — секрет. Бизнес-метрики, конкурентные данные.
Гибридный подход (рекомендуемый)
-- В БД храним два ID: CREATE TABLE orders ( id UUID PRIMARY KEY DEFAULT uuidv7(), -- v7 для performance public_id UUID NOT NULL UNIQUE DEFAULT uuid_v4(), -- v4 для API created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), -- ... остальные поля ); -- Индекс на public_id для API endpoints CREATE UNIQUE INDEX ON orders (public_id); -- Внутренние сервисы используют id (v7) -- Frontend / API получает только public_id (v4)
Генерация в коде
Node.js
// uuid 10.0+ (с 2024)
import { v4 as uuidv4, v7 as uuidv7 } from 'uuid';
const v4Id = uuidv4();
// 'f47ac10b-58cc-4372-a567-0e02b2c3d479'
const v7Id = uuidv7();
// '018f7a8c-5d4e-7c2a-9f1b-3a5c7e9d2b4f'
// Извлечь timestamp из v7
const timestamp = parseInt(v7Id.replace(/-/g, '').slice(0, 12), 16);
const date = new Date(timestamp);Python
# pip install uuid7
import uuid
from uuid7 import uuid7
v4 = uuid.uuid4()
# UUID('f47ac10b-58cc-4372-a567-0e02b2c3d479')
v7 = uuid7()
# UUID('018f7a8c-5d4e-7c2a-9f1b-3a5c7e9d2b4f')PostgreSQL 17+
-- В PostgreSQL 17 (2024) добавлены нативные функции SELECT uuidv7(); -- 018f7a8c-5d4e-7c2a-9f1b-3a5c7e9d2b4f SELECT gen_random_uuid(); -- v4 (доступен с PostgreSQL 13) -- f47ac10b-58cc-4372-a567-0e02b2c3d479 -- Использование как DEFAULT CREATE TABLE orders ( id UUID PRIMARY KEY DEFAULT uuidv7() );
Альтернативы UUID
- nanoid. 21 символ, 126 бит. Короче UUID. Без timestamp. URL-safe.
- ksuid (Stripe). 27 символов, sorted by time, без дефисов. Близок к v7.
- cuid2. Современная альтернатива nanoid с лучшими свойствами.
- ULID. Похож на v7, тоже timestamp + random. 26 символов в Crockford base32.
- Snowflake (Twitter). 64-битный sequential ID + machine ID + sequence. Требует координации между генераторами.
- RFC 9562 — Universally Unique IDentifiers (UUIDs). IETF. datatracker.ietf.org/doc/html/rfc9562. 2024.
- PostgreSQL 17 — UUID v7 support. PostgreSQL Global Development Group. postgresql.org/docs/17/functions-uuid.html. 2024.
- uuid npm — modern UUID library. uuidjs. github.com/uuidjs/uuid. 2024.
