Нужен GUID: подойдёт этот же генератор
UUID и GUID — одно и то же, разное только название, второе прижилось в экосистеме Microsoft. На практике отличается лишь запись. В реестре Windows и в коде на C# идентификатор часто носят в фигурных скобках: {6f9619ff-8b86-d011-b42d-00cf4fc964ff}. Скобки — часть оформления, а не значения, перед сравнением или записью в базу их снимают.
Четыре формата записи и где какой нужен
Один и тот же UUID можно записать по-разному, на значение это не влияет. Но принимающая сторона обычно ждёт конкретный вид:
| Формат | Пример | Когда нужен |
|---|---|---|
| Стандартный | 9efcd058-79dd-485f-94a0-22cf61231d0f | Канонический вид из RFC 9562. Его ждут PostgreSQL, MySQL и большинство API |
| Без дефисов | 9efcd05879dd485f94a022cf61231d0f | 32 символа, компактнее в URL и ключах кэша, дефисы всегда можно вернуть |
| Верхний регистр | 9EFCD058-79DD-485F-94A0-22CF61231D0F | Привычен в мире Microsoft. Сравнивать UUID нужно без учёта регистра |
| URN | urn:uuid:9efcd058-79dd-485f-94a0-22cf61231d0f | Форма с префиксом для XML, RDF и других мест, где нужен полноценный URI |
Какую кнопку версии нажать
Короткая шпаргалка по переключателю выше. Почему версии устроены именно так и чем v7 лучше v1, разобрано в статье про версии UUID.
| Версия | Из чего собран | Когда брать |
|---|---|---|
v4 | 122 случайных бита | Значение по умолчанию. Берите, если ID не станет первичным ключом большой таблицы |
v7 | Время + случайность | Лучший выбор под первичный ключ, сортируется по времени создания |
v1 | Время + MAC-адрес | Наследие. Раскрывает устройство-источник, для новых проектов не нужен |
nil | Только нули | Заглушка «идентификатора нет», удобнее NULL, когда колонка обязательная |
Как сгенерировать UUID в коде
Онлайн-генератор удобен, когда нужно несколько значений руками: для сида базы, теста или заглушки в конфиге. В самом приложении UUID генерируют средствами языка или СУБД, отдельная библиотека почти нигде уже не нужна:
| Среда | Вызов |
|---|---|
| PostgreSQL 13+ | gen_random_uuid() |
| PostgreSQL (v7) | uuidv7(), начиная с версии 18 |
| MySQL 8+ | UUID() |
| JavaScript / Node 19+ | crypto.randomUUID() |
| Python | import uuid; uuid.uuid4() |
| Go | github.com/google/uuid → uuid.New() |
| C# / .NET | Guid.NewGuid() |
| Java | UUID.randomUUID() |
Все перечисленные функции дают v4 и берут случайность у криптографического генератора операционной системы. А вот Math.random() для сборки UUID вручную не годится. Он не криптостойкий, значения из него предсказуемы, и «уникальность» такого идентификатора держится только на удаче.
Как понять, что перед вами UUID и какой версии
Строка всегда состоит из 32 шестнадцатеричных символов, разбитых дефисами по схеме 8-4-4-4-12. Версия и вариант зашиты прямо в неё, и прочитать их можно глазами:
9efcd058-79dd-485f-94a0-22cf61231d0f
- Первый символ третьей группы задаёт версию. Здесь
4, то есть случайный UUID. У v7 на этом месте будет7. - Первый символ четвёртой группы задаёт вариант. Значения
8,9,aилиbозначают вариант RFC, тот, что используют все современные библиотеки.
Генератор выше показывает разобранные версию и вариант под полем. По ним удобно проверить чужой идентификатор, не считая символы вручную.
Чего UUID не даёт
Уникальность — единственное, что гарантирует формат. Отсюда ограничения, о которые спотыкаются регулярно.
- Это не секрет. UUID v4 нельзя угадать, но он попадает в адресную строку, историю браузера, логи и заголовок
Referer. Как токен сессии или ссылка на сброс пароля он не годится, для этого нужны значения с ограниченным сроком жизни. - v1 и v7 раскрывают время. Из такого идентификатора извлекается момент создания записи с точностью до миллисекунд, а v1 выдаёт ещё и сетевой адрес машины. Там, где порядок и время регистрации не должны быть видны снаружи, берите v4.
- Он не защищает от дублей. Два вызова генератора для одной и той же сущности дадут две разные строки. Уникальность идентификатора и уникальность данных — разные вещи, и вторую по-прежнему обеспечивает ограничение в базе.
- Он не бесплатный по месту. UUID занимает 16 байт против 4 у обычного
int, и эти байты повторяются в каждом внешнем ключе и в каждом индексе, который на них ссылается. На сотне строк разницы нет, на десятках миллионов она заметна на диске и в памяти под индексы.
Разбор всех версий и пространства значений, из-за которого столкновение практически невозможно, есть в статье Что такое UUID и чем отличаются версии v1, v4, v7.