Данные

Руководство по UUID: v4 против v7 и UUID как первичный ключ в базе данных

Строки вроде 550e8400-e29b-41d4-a716-446655440000 повсюду обозначают заказы, файлы и API-запросы. Узнайте, как генерируются UUID и какую версию выбрать.

Что такое UUID

UUID (Universally Unique Identifier) — это 128-битный идентификатор, который позволяет любому создавать неконфликтующие ID без обращения к центральному серверу. В Microsoft его называют GUID. Действующий стандарт — RFC 9562, опубликованный в 2024 году.

Он записывается как 32 шестнадцатеричные цифры, разделённые дефисами на группы 8-4-4-4-12, всего 36 символов. Первая цифра третьей группы указывает версию: xxxxxxxx-xxxx-4xxx-... — это v4, а 7xxx — v7.

Версии вкратце

Сегодня обычно выбирают v4 для общих задач и v7, когда важны порядок и скорость вставки, например для первичных ключей в базе данных.

  • v1: сочетает метку времени и MAC-адрес машины. Упорядочена по времени, но может раскрыть сведения об оборудовании.
  • v3 и v5: хешируют пространство имён и имя, поэтому одинаковые входные данные всегда дают одинаковый UUID (v3 использует MD5, v5 — SHA-1).
  • v4: 122 случайных бита. Самая распространённая и простая в реализации.
  • v7: 48-битная метка времени Unix в миллисекундах, за которой следуют случайные биты. Сортируется в порядке создания.

Неужели UUID действительно не совпадают?

Случайная часть UUID v4 занимает 122 бита, что даёт около 5,3 × 10^36 возможных значений. По парадоксу дней рождения, чтобы вероятность хотя бы одного дубликата достигла 50 %, нужно около 2,7 × 10^18 UUID — примерно миллиард в секунду в течение 85 лет. На практике коллизий не бывает.

Но это верно, только если случайные числа действительно случайны. Дубликаты фиксировались после клонирования виртуальных машин с одинаковым состоянием генератора случайных чисел или в самописных реализациях с предсказуемыми функциями случайных чисел. Используйте стандартную функцию UUID вашей платформы.

UUID как первичный ключ

Ключи UUID можно генерировать сразу на многих серверах, и они не раскрывают число записей. С автоинкрементными целыми числами URL вроде /orders/1052 позволяет конкурентам оценить объём ваших заказов.

Плата за это — размер и порядок. UUID занимает 16 байт, вдвое больше 8-байтового целого, а в виде строки из 36 символов — ещё больше. Поскольку v4 полностью случаен, новые строки попадают в произвольные места индекса B-tree, что вызывает частые разделения страниц и замедляет запись. v7 растёт со временем и в основном избегает этой проблемы.

  • PostgreSQL: используйте встроенный тип uuid (16 байт).
  • MySQL: храните как BINARY(16); начиная с версии 8.0 есть UUID_TO_BIN.
  • SQL Server: используйте тип uniqueidentifier.

Когда UUID не стоит использовать как секрет

UUID задуман как уникальное имя, а не как секрет, который невозможно угадать. v1 и v7 содержат метку времени, поэтому часть битов предсказуема. Чувствительные значения, такие как токены сброса пароля и секреты API, следует генерировать из достаточного количества криптографически стойких случайных байтов.

Создавайте сколько угодно UUID в генераторе UUID от AIBIZAP, а для секретов используйте генератор клиентских учётных данных. Если вы проектируете таблицы по образцам JSON, удобно дополнительно воспользоваться генератором DDL из JSON.

Попробуйте с этими инструментами

Другие руководства

Все руководства