👩💻 Генерация ключей в SQL: что выбрать — UUID, INT или BIGINT?
При проектировании таблиц в реляционных базах данных важно выбрать тип данных для первичного ключа. От него зависят скорость запросов, обеспечение уникальности, масштабируемость и даже архитектура системы. Даже если вы не проектируете БД, понимание ключей поможет в работе с данными.
Если необходимо, можете прочитать пост про первичный ключ и базовый автоинкримент тут
В этом посте рассмотрим три популярных способа генерации первичных ключей: INT, BIGINT и UUID.
🛠 INT — автоинкрементный числовой ключ
Используется по умолчанию в большинстве проектов. Он требует минимум места, обеспечивает быструю сортировку и фильтрацию по индексу, хорошо читается в логах, легко реализуется средствами СУБД. Но у INT есть потолок (2.1 млрд значений) и ограниченная масштабируемость: при распределении на несколько серверов ID могут пересекаться. А ещё ID легко угадываются, что делает структуру базы предсказуемой.
☑️ Подходит для централизованных систем с небольшим или средним объёмом данных, занимает минимум места в памяти и индексах, понятен при отладке и в логах.
☑️Быстрота отличная производительность при сортировке и фильтрации по индексу.
☑️ легко реализуется с AUTO_INCREMENT или SERIAL.
❌ ID легко предсказуемы, что может косвенно раскрывать объёмы или порядок операций, также при ошибке планирования в крупных системах может потребоваться переход на BIGINT.
❌ Сложность масштабирования, трудно синхронизировать генерацию ID между несколькими узлами.
🛠 BIGINT — INT с запасом на вырост
То же самое, только 64 бита. Решает проблему переполнения — хватит на миллиарды строк. Сохраняет читаемость, скорость и простоту реализации. Поддерживается всеми современными СУБД. Но индекс и таблицы с такими ключами весят больше. А генерация ID всё ещё централизованная, что не даёт гибкости.
☑️ Уместен в крупных монолитных системах с интенсивной вставкой данных (например, финансы, e-commerce).
☑️ Сохраняет преимущества INT — скорость, простота, читабельность.
❌ По-прежнему требует централизованной генерации: не решает задачу горизонтального масштабирования.
🛠 UUID (Universally Unique Identifier)
UUID создаётся независимо, без единого центра, что делает его идеальным для микросервисов, Kafka, offline-режимов и распределённых архитектур. Его сложно предсказать — это повышает безопасность. UUID легко интегрируется в API и события. Но UUID весит больше (16 байт), хуже индексируется, не читается глазами, не сортируется. Это может замедлять JOIN и вставки. Если важна хоть какая-то упорядоченность, используйте UUID v1 или v7 — они содержат метку времени.
☑️ Лучший выбор для распределённых систем, событийных шин, микросервисов, широко используется в API, Kafka, распределённых брокерах
☑️ Можно безопасно генерировать на любом сервере, без централизованного координирующего узла
❌ Неудобны при ручной работе: тяжело читаются и неудобны в логах, CLI.
❌ 16 байт против 4–8 байт у числовых типов, что замедляет индексацию и JOIN
🧊 Объемы генерации ключей в экземпляре таблицы
Вы можете создать не более примерно 2 миллиардов уникальных записей с автоинкрементом INT. Если же использовать BIGINT, то его диапазон гораздо шире — он позволяет задать свыше 9 квинтиллионов уникальных значений, что на практике практически никогда не достигается.
С UUID ситуация другая: это 128-битное значение, которое генерируется случайным или псевдослучайным образом. Количество возможных значений настолько велико (2^128), что даже при создании миллиардов UUID-ключей в секунду вероятность столкнуться с дублем за всю историю человечества минимальна. Однако при этом UUID занимает больше места, как на диске, так и в оперативной памяти, и может замедлять индексацию.
Что выбрать?
➖ Централизованная база — INT
➖ Крупная монолитная система — BIGINT
➖ Распределённые микросервисы — UUID
➖ Нужно скрыть структуру и объём данных — UUID
➖ Приоритет на компактность и быстрые JOIN/сортировки — INT / BIGINT
#UUID #INT #BIGINT
📱 Подписаться на канал
💻 Курс автора по SQL DDL
При проектировании таблиц в реляционных базах данных важно выбрать тип данных для первичного ключа. От него зависят скорость запросов, обеспечение уникальности, масштабируемость и даже архитектура системы. Даже если вы не проектируете БД, понимание ключей поможет в работе с данными.
Если необходимо, можете прочитать пост про первичный ключ и базовый автоинкримент тут
В этом посте рассмотрим три популярных способа генерации первичных ключей: INT, BIGINT и UUID.
🛠 INT — автоинкрементный числовой ключ
Используется по умолчанию в большинстве проектов. Он требует минимум места, обеспечивает быструю сортировку и фильтрацию по индексу, хорошо читается в логах, легко реализуется средствами СУБД. Но у INT есть потолок (2.1 млрд значений) и ограниченная масштабируемость: при распределении на несколько серверов ID могут пересекаться. А ещё ID легко угадываются, что делает структуру базы предсказуемой.
☑️ Подходит для централизованных систем с небольшим или средним объёмом данных, занимает минимум места в памяти и индексах, понятен при отладке и в логах.
☑️Быстрота отличная производительность при сортировке и фильтрации по индексу.
☑️ легко реализуется с AUTO_INCREMENT или SERIAL.
❌ ID легко предсказуемы, что может косвенно раскрывать объёмы или порядок операций, также при ошибке планирования в крупных системах может потребоваться переход на BIGINT.
❌ Сложность масштабирования, трудно синхронизировать генерацию ID между несколькими узлами.
🛠 BIGINT — INT с запасом на вырост
То же самое, только 64 бита. Решает проблему переполнения — хватит на миллиарды строк. Сохраняет читаемость, скорость и простоту реализации. Поддерживается всеми современными СУБД. Но индекс и таблицы с такими ключами весят больше. А генерация ID всё ещё централизованная, что не даёт гибкости.
☑️ Уместен в крупных монолитных системах с интенсивной вставкой данных (например, финансы, e-commerce).
☑️ Сохраняет преимущества INT — скорость, простота, читабельность.
❌ По-прежнему требует централизованной генерации: не решает задачу горизонтального масштабирования.
🛠 UUID (Universally Unique Identifier)
UUID создаётся независимо, без единого центра, что делает его идеальным для микросервисов, Kafka, offline-режимов и распределённых архитектур. Его сложно предсказать — это повышает безопасность. UUID легко интегрируется в API и события. Но UUID весит больше (16 байт), хуже индексируется, не читается глазами, не сортируется. Это может замедлять JOIN и вставки. Если важна хоть какая-то упорядоченность, используйте UUID v1 или v7 — они содержат метку времени.
☑️ Лучший выбор для распределённых систем, событийных шин, микросервисов, широко используется в API, Kafka, распределённых брокерах
☑️ Можно безопасно генерировать на любом сервере, без централизованного координирующего узла
❌ Неудобны при ручной работе: тяжело читаются и неудобны в логах, CLI.
❌ 16 байт против 4–8 байт у числовых типов, что замедляет индексацию и JOIN
🧊 Объемы генерации ключей в экземпляре таблицы
Вы можете создать не более примерно 2 миллиардов уникальных записей с автоинкрементом INT. Если же использовать BIGINT, то его диапазон гораздо шире — он позволяет задать свыше 9 квинтиллионов уникальных значений, что на практике практически никогда не достигается.
С UUID ситуация другая: это 128-битное значение, которое генерируется случайным или псевдослучайным образом. Количество возможных значений настолько велико (2^128), что даже при создании миллиардов UUID-ключей в секунду вероятность столкнуться с дублем за всю историю человечества минимальна. Однако при этом UUID занимает больше места, как на диске, так и в оперативной памяти, и может замедлять индексацию.
Что выбрать?
➖ Централизованная база — INT
➖ Крупная монолитная система — BIGINT
➖ Распределённые микросервисы — UUID
➖ Нужно скрыть структуру и объём данных — UUID
➖ Приоритет на компактность и быстрые JOIN/сортировки — INT / BIGINT
#UUID #INT #BIGINT
📱 Подписаться на канал
💻 Курс автора по SQL DDL