Генератор UUID · форматUUID v4 — генератор и как он устроен
Четвёртая версия — 122 случайных бита и шесть служебных. Её выдают по умолчанию почти все библиотеки и базы данных: она ничего не раскрывает о том, где и когда создана, и не требует никакой координации между машинами.
Идентификатор, который не должен ничего выдавать: токены, ключи запросов, имена загруженных файлов.
Первичный ключ небольшой таблицы или распределённой системы, где порядок вставки не важен.
Любое место, где нужен «просто уникальный ID», — это значение по умолчанию.
Чем отличается от соседей
Главный сосед — v7. У v4 нет порядка: новые значения разбросаны по всему диапазону, и в большой таблице с индексом по ключу каждая вставка попадает в случайное место индекса. v7 начинается с времени и вставляется в конец. Если таблица растёт на миллионы строк — берите v7, иначе разница незаметна.
Почти везде это одна встроенная функция: в браузере и Node.js — crypto.randomUUID(), в Python — uuid.uuid4(), в Java — UUID.randomUUID(), в C# — Guid.NewGuid(), в PostgreSQL начиная с 13-й версии — gen_random_uuid(). Все они выдают четвёртую версию из криптографического генератора. Сторонняя библиотека нужна разве что для старых окружений, где этих функций ещё нет.
Это номер версии: первая цифра третьей группы хранит его в четырёх битах, и у четвёртой версии там всегда 4. Первая цифра четвёртой группы — вариант стандарта, у RFC 9562 это 8, 9, a или b. Шесть бит из 128 служебные, поэтому случайных в v4 ровно 122, а по этим двум позициям версию определяют на глаз.
Только если он получен из криптографического генератора, как здесь и в crypto.randomUUID: тогда 122 бита не угадать перебором. Но RFC 9562 прямо советует не считать UUID секретом — некоторые библиотеки берут обычный псевдослучайный генератор, а логи и адресная строка легко раскрывают значение. Для токенов доступа надёжнее отдельный генератор секретов с явной длиной.
Из-за отсутствия порядка. Индекс базы — упорядоченное дерево, и каждая новая случайная запись попадает в случайную его страницу: страницы делятся, кеш работает хуже, индекс разрастается. На маленьких таблицах этого не видно, на десятках миллионов строк — заметно. Плюс ключ занимает 16 байт против 8 у целого числа. Поэтому для ключей больших таблиц берут v7.
Для ключа большой таблицы и всего, что удобно сортировать по самому идентификатору, — v7: он упорядочен по времени создания. Для значений, которые видит посторонний, — v4: по нему нельзя узнать, когда запись появилась. Если сомневаетесь, а таблица небольшая, разницы на практике нет, и v4 остаётся безопасным значением по умолчанию.
Посмотрите на первую цифру третьей группы — должна быть 4 — и на первую цифру четвёртой: 8, 9, a или b. Строго это делает поле «Проверка» на странице генератора: оно принимает значение с дефисами и без, в фигурных скобках и с префиксом urn:uuid, называет версию и вариант и показывает, из каких частей состоит идентификатор.