Антипаттерн: использование UUID как Primary Key без оглядки

GuDron

dumpz.ws
Admin
Регистрация
28 Янв 2020
Сообщения
10,005
Реакции
1,564
Credits
35,672
Антипаттерн: использование UUID как Primary Key без оглядки

На первый взгляд, UUID — классный способ генерировать уникальные идентификаторы:
– не зависят от последовательности
– удобны для распределённых систем
– безопасны для внешнего экспонирования

Но если ты просто заменишь SERIAL или BIGINT на UUID в качестве PK — жди сюрпризов:

В чём подвох:

– Производительность INSERT'ов резко падает: UUID случайные → нет locality → индекс (обычно B-Tree) постоянно фрагментируется
– Индексы пухнут: UUID = 16 байт, BIGINT = 8 байт. Разница кажется небольшой, но на больших объёмах — это боль
– Чтение медленнее: за счёт увеличенного размера индексов и меньшего кэш-хита

Как избежать:
1. Если нет жёсткой необходимости в UUID — не используй их как PK
2. Нужен UUID? Сделай его вторичным индексом, а PK оставь автоинкрементным
3. Или хотя бы используй UUID v7 (новый стандарт с time-based префиксом) — он улучшает локальность по сравнению с v4

Пример:
SQL:
CREATE TABLE users (
    id BIGSERIAL PRIMARY KEY,
    public_id UUID DEFAULT gen_random_uuid() UNIQUE,
    name TEXT
);
→ Внутри БД — быстрый BIGINT,
→ Для внешних API — UUID. Удобно и производительно.