BIGINT — что это за тип данных и когда его использовать в базе данных: инструкция для новичка
BIGINT — это целочисленный тип данных, который хранит числа от минус 9,2 квинтиллиона до 9,2 квинтиллиона и занимает 8 байт в таблице. Разбираем, чем он отличается от INT, как задать его в MySQL и PostgreSQL, сколько места он реально съедает на сервере и когда выбор BIGINT — ошибка. Другие практические разборы читайте в блоге.

Коротко
Главные выводы статьи о теме «BIGINT тип данных» в семи пунктах:
- BIGINT занимает 8 байт (64 бита) в MySQL, PostgreSQL и MS SQL Server
- Диапазон signed BIGINT — от -9 223 372 036 854 775 808 до 9 223 372 036 854 775 807
- Диапазон unsigned BIGINT в MySQL — от 0 до 18 446 744 073 709 551 615
- INT занимает вдвое меньше — 4 байта, максимум около 2,1 млрд
- 1 млн строк со столбцом BIGINT ≈ 8 МБ только под данные, плюс место под индекс
- В PostgreSQL нет UNSIGNED — для запрета отрицательных чисел используют CHECK
- Автоинкремент задаётся как AUTO_INCREMENT в MySQL и BIGSERIAL в PostgreSQL
Что такое BIGINT и зачем он нужен
BIGINT — это целочисленный тип данных для очень больших целых чисел. Он занимает 8 байт (64 бита). В варианте со знаком (signed) он хранит значения от -9 223 372 036 854 775 808 до 9 223 372 036 854 775 807.
В MySQL есть беззнаковый вариант BIGINT UNSIGNED. Его диапазон — от 0 до 18 446 744 073 709 551 615. В PostgreSQL модификатора UNSIGNED нет, поэтому отрицательные значения там запрещают ограничением CHECK. Тип BIGINT также поддерживают MS SQL Server (Microsoft SQL Server) и SQLite. SQLite принимает объявление BIGINT, но хранит такие значения как INTEGER — до 8 байт на число.
Обычный INT занимает 4 байта, а его максимум — около 2,1 млрд. Для крупного проекта этого может не хватить: счётчик упрётся в предел, и новые строки перестанут добавляться, база вернёт ошибку. С BIGINT запаса хватит на всё время работы проекта.
Задачи, где чаще всего нужен BIGINT:
- ID (идентификаторы) пользователей, заказов и сообщений в крупных сервисах;
- счётчики событий: просмотры, клики, записи логов;
- временные метки Unix в миллисекундах — например, значение 1 790 000 000 000 уже не помещается в
INT; - денежные суммы в копейках или центах — так вы избежите ошибок округления, которые бывают у дробных чисел.
Как BIGINT хранится и работает на уровне базы данных
СУБД резервирует под каждый числовой столбец фиксированное количество байт независимо от того, какое значение вы реально записали. Для BIGINT это всегда 8 байт (64 бита) — и в MySQL, и в PostgreSQL, и в MS SQL Server. Даже если в столбце хранится число 5, движок всё равно выделит под него полные 8 байт, потому что размер задаётся типом, а не содержимым.
Чем крупнее тип столбца, тем больше «весит» каждая строка и каждая запись в индексе. Первичный ключ обычно попадает не только в основную таблицу, но и во все вторичные индексы как ссылка на строку, поэтому его размер умножается на количество индексов. Разница между INT (4 байта) и BIGINT (8 байт) кажется незначительной на одной строке, но на таблице из 1 млн строк она превращается в дополнительные мегабайты только на индексах.
Более крупный первичный ключ замедляет операции JOIN: базе приходится сравнивать больше байт на каждую пару строк, а сами индексы занимают больше места в памяти и хуже помещаются в кэш. В результате при том же объёме оперативной памяти сервер держит в кэше меньше «горячих» страниц индекса, и часть запросов чаще уходит на диск.
| Тип | Размер | Максимум (примерно) |
|---|---|---|
TINYINT |
1 байт | 255 |
SMALLINT |
2 байта | 65 тыс. |
MEDIUMINT |
3 байта | 16,7 млн |
INT |
4 байта | 2,1 млрд |
BIGINT |
8 байт | 9,2 квинтиллиона |
Что важно учитывать при выборе размера первичного ключа:
- Размер столбца напрямую влияет на объём индекса — 1 млн строк с
BIGINTдобавляет около 8 МБ только на сами данные ключа. - Вторичные индексы хранят копию первичного ключа, поэтому лишние байты множатся на число индексов в таблице.
- Меньший индекс лучше помещается в кэш сервера, а значит,
JOINи поиск по ключу выполняются быстрее. - Выигрыш в скорости на маленьких таблицах незаметен, но на десятках миллионов строк становится ощутимым.
Производительность базы данных зависит не только от типов столбцов, но и от объёма оперативной памяти сервера, где хранится кэш индексов: чем больше RAM, тем больше «горячих» страниц индекса остаётся в памяти. Если памяти не хватает, выберите VPS с большим объёмом RAM.

Как задать BIGINT в таблице: пошаговая инструкция
Тип BIGINT задаётся прямо в команде CREATE TABLE так же просто, как обычный INT. Разница только в объёме памяти: 8 байт против 4 байт у INT, и диапазоне значений — до 9 223 372 036 854 775 807 у знакового варианта. Дальше нужно решить пару деталей: нужен ли запрет отрицательных чисел и автоматическая генерация значений для первичного ключа.
Если таблица уже существует и использует INT, который скоро упрётся в потолок 2,1 млрд строк, столбец можно перевести в BIGINT без пересоздания таблицы. Такая миграция временно блокирует таблицу, поэтому её стоит планировать на период низкой нагрузки. Проверить структуру таблицы после любых изменений удобно через панель управления базой — например, в phpMyAdmin; как его установить и открыть структуру таблицы, разобрано в статье «phpMyAdmin: настройка и использование».
Порядок создания и миграции столбца BIGINT:
- Создайте таблицу с полем
BIGINT:CREATE TABLE orders (id BIGINT NOT NULL); - В MySQL при необходимости запретите отрицательные значения флагом
UNSIGNED:id BIGINT UNSIGNED NOT NULL— диапазон станет от 0 до 18 446 744 073 709 551 615. - В PostgreSQL флага
UNSIGNEDнет, поэтому запрет отрицательных чисел задаётся черезCHECK (id >= 0). - Добавьте автоинкремент: в MySQL —
AUTO_INCREMENT, в PostgreSQL — типBIGSERIALвместоBIGINTили конструкцияGENERATED ALWAYS AS IDENTITY. - Назначьте столбец первичным ключом:
PRIMARY KEY (id). - Проверьте итоговую структуру: в MySQL командой
DESCRIBE orders;, в PostgreSQL —\d ordersв консолиpsql. - Для миграции существующего столбца из
INTв MySQL выполнитеALTER TABLE orders MODIFY COLUMN id BIGINT UNSIGNED;. - В PostgreSQL аналогичная команда —
ALTER TABLE orders ALTER COLUMN id TYPE BIGINT;. - Учтите, что на время выполнения
ALTER TABLEтаблица блокируется для записи, а на таблице из 1 млн строк операция затронет около 8 МБ данных плюс место под индекс — запускайте миграцию в окне обслуживания.

Сколько места и ресурсов сервера съедает BIGINT
Место под столбец BIGINT считается напрямую: 8 байт на строку. При 1 млн строк это около 8 МБ только под сами данные, без учёта индекса. Индекс по этому же столбцу обычно занимает сопоставимый или больший объём из-за служебной структуры, поэтому реальный расход выше цифры «8 байт на строку».
На таблице в 100 млн строк расход уже заметен: около 800 МБ под данные столбца и, с учётом индекса, суммарно порядка 1,6 ГБ дискового пространства. Для сравнения, столбец INT занимает 4 байта и на тех же 100 млн строк съест примерно вдвое меньше — около 400 МБ под данные. Разница в 2 раза кажется небольшой на одном столбце, но при нескольких внешних ключах BIGINT в разных таблицах она складывается в ощутимые гигабайты.
Рост таблицы напрямую бьёт по ресурсам VPS (Virtual Private Server, виртуальный выделенный сервер): база данных держит активные индексы в оперативной памяти для быстрых запросов, и чем больше места занимает индекс, тем больше RAM (Random Access Memory, оперативная память) требуется, чтобы он не вытеснялся на диск. Если памяти не хватает, СУБД (система управления базами данных) начинает читать индекс с диска при каждом запросе, а это заметно замедляет выборки.
Как BIGINT влияет на диск, индексы и память:
- Дисковое место растёт линейно: 10 млн строк — около 80 МБ под столбец, 1 млрд строк — около 8 ГБ
- Индексы обычно требуют больше места, чем сами данные столбца
- При нехватке RAM под индексы растёт число обращений к диску и падает скорость запросов
Если таблица рассчитана на рост до сотен миллионов строк, закладывайте запас по RAM и диску заранее — на VPS с фиксированными ресурсами это проще, чем экстренно расширять сервер под нагрузкой. Актуальные конфигурации под такие задачи можно посмотреть в рейтинге VPS-серверов.
Выбрать сервер с запасом по диску для роста базы
Если база вырастет до сотен миллионов строк, заранее заложите запас по диску — посмотрите тарифы VPS с расширяемым хранилищем.
Ошибки при использовании BIGINT и как их избежать
С BIGINT ошибаются в обе стороны: ставят его везде «на всякий случай» или, наоборот, выбирают INT там, где данные быстро растут. Ниже разберём каждую ошибку по отдельности — от лишнего места на диске до несовместимого с PostgreSQL синтаксиса.
Первая ошибка: BIGINT во всех таблицах
Новички часто перебарщивают с типами данных: ставят BIGINT сразу во все таблицы, хотя реальный диапазон значений умещается в INT. В результате база данных занимает лишние 4 байта на каждой строке каждого такого столбца — на таблице в 10 млн строк это уже 40 МБ впустую, не считая места под индексы.
Как решить: не ставьте BIGINT по умолчанию — оценивайте реальный максимум значений заранее.
Вторая ошибка: INT для быстрорастущих данных
Обратная ситуация: столбец объявили как INT, а данные росли быстрее, чем ожидали. Когда счётчик подходит к пределу около 2,1 млрд, сервер начинает отдавать ошибку Out of range value, и вставка новых строк останавливается.
Как решить: менять тип на живой таблице без простоя нужно осторожно — через создание нового столбца, копирование данных пакетами по 10 000–50 000 строк и последующее переименование, а не одной командой ALTER TABLE на многомиллионной таблице. Так таблица не заблокируется.
Третья ошибка: разные типы в JOIN
Если внешний ключ имеет тип BIGINT, а столбец, на который он ссылается, — INT, база данных не может использовать индекс напрямую и вынуждена приводить типы на лету. Это резко замедляет выборку на больших объёмах.
Как решить: проверяйте типы столбцов по обе стороны JOIN — они должны совпадать.
Четвёртая ошибка: синтаксис MySQL в PostgreSQL
Разработчики копируют синтаксис MySQL в PostgreSQL и получают ошибку при попытке написать BIGINT UNSIGNED. В PostgreSQL нет модификатора UNSIGNED — эта возможность MySQL здесь отсутствует.
Как решить: если нужно запретить отрицательные числа в столбце BIGINT, используйте ограничение CHECK (id >= 0) при создании таблицы, а автоинкремент задавайте через BIGSERIAL. Короче говоря, UNSIGNED в PostgreSQL заменяется на CHECK.
Выбирайте тип по реальному диапазону, следите за совпадением типов в связях и мигрируйте пакетами. Если сомневаетесь, что текущий тарифный план справится с ростом таблиц и индексов после миграции на BIGINT, закажите VPS с запасом по диску и памяти.
BIGINT, INT и UUID: что выбрать для первичного ключа
Три типа отличаются прежде всего размером и способом генерации значения. INT занимает 4 байта и подходит для справочников с ограниченным числом строк — списка стран, категорий товаров, статусов заказа. BIGINT занимает 8 байт и держит диапазон почти до 9,2 квинтиллиона значений, поэтому годится для больших таблиц вроде логов, транзакций или сообщений. UUID (Universally Unique Identifier, «универсальный уникальный идентификатор») занимает 16 байт и генерируется без обращения к базе, что делает его удобным для распределённых систем.
Разница в размере напрямую влияет на скорость поиска по индексу. BIGINT — это просто число, и вставка новых строк идёт последовательно за счёт AUTO_INCREMENT в MySQL или BIGSERIAL в PostgreSQL. Индекс растёт предсказуемо, без перестроения страниц. UUID обычно генерируется случайно, поэтому новая запись попадает в произвольное место индекса, а не в конец — это увеличивает фрагментацию и замедляет вставку на больших объёмах.
Читаемость тоже играет роль: id=48291 легко произнести в поддержке или найти в логах, а строку вида a1b2c3d4-... — нет. Зато UUID не выдаёт во внешнем API количество записей в таблице и не пересекается при слиянии данных с разных серверов, что важно для микросервисов.
| Тип | Размер | Диапазон / вид значения | Где уместен |
|---|---|---|---|
INT |
4 байта | до ~2,1 млрд | справочники, категории |
BIGINT |
8 байт | до 9 223 372 036 854 775 807 | монолитная база, логи, транзакции |
UUID |
16 байт | случайная строка из 36 символов | распределённые системы, синхронизация между серверами |
Итог простой: для одиночного сервера баз данных берите BIGINT — он вдвое компактнее UUID и быстрее в индексе за счёт последовательной вставки. Для справочников с несколькими сотнями строк хватит INT. UUID выбирайте только когда записи создаются на разных серверах одновременно и им нельзя пересекаться. Если система развёрнута на VPS (Virtual Private Server, «виртуальный выделенный сервер») и вы подбираете конфигурацию под нагрузку базы данных, посмотрите разбор ещё одной серверной СУБД.

Когда BIGINT не подходит
BIGINT занимает 8 байт на каждую строку, и для справочника из десятка статусов или ролей это расточительство без всякой пользы. Если значений в столбце заведомо мало — используйте TINYINT (1 байт, до 255 значений) или SMALLINT (2 байта, до 32 767). На таблице в 1 млн строк разница между BIGINT и TINYINT — это уже 7 МБ лишнего места только на один столбец, а с учётом индекса ещё больше.
С деньгами BIGINT справляется, только пока сумма хранится целым числом минимальных единиц — копеек или центов. Если же в расчётах появляются доли копейки, проценты, курсы валют или округление по правилам бухгалтерии, нужен тип DECIMAL с фиксированной точностью — он хранит именно ту сумму, которая была введена, без ошибок округления, характерных для чисел с плавающей точкой. Логическому значению «да/нет» тоже не нужны 8 байт — для этого есть BOOLEAN, который в большинстве СУБД занимает 1 байт или даже меньше.
Отдельный случай — распределённые системы, где несколько серверов пишут данные одновременно и не могут договориться о едином счётчике. Центральный AUTO_INCREMENT или BIGSERIAL здесь превращается в узкое место и точку отказа. Для таких сценариев подойдут UUID или ULID — идентификаторы, которые генерируются независимо на каждом узле без риска коллизий.
Какой тип выбрать вместо BIGINT в разных случаях:
- Справочник ролей или статусов — TINYINT/SMALLINT, а не BIGINT про запас
- Суммы с дробными расчётами (проценты, курсы, доли копейки) — DECIMAL с фиксированной точностью; целые копейки можно хранить и в BIGINT
- Логические флаги — BOOLEAN, а не число
- Распределённая запись без общего счётчика — UUID или ULID
Главное правило — выбирать тип под реальный объём и характер данных, а не «на всякий случай». Если вы подбираете сервер под такую базу, начните с подходящего тарифа VPS.
Частые вопросы
Чем BIGINT отличается от INT?
Сколько байт занимает BIGINT?
Какой максимальный BIGINT в MySQL?
Можно ли сделать BIGINT UNSIGNED в PostgreSQL?
Нужен ли BIGINT для ID пользователей на маленьком проекте?
Как перевести столбец INT в BIGINT без потери данных?
BIGINT и BIGSERIAL — это одно и то же?
Замедляет ли BIGINT работу базы данных?
Что выбрать: BIGINT или UUID для первичного ключа?
Можно ли хранить деньги в BIGINT?
Итоговый чек-лист
Используйте этот список как финальную проверку: каждый пункт — короткий вывод из статьи выше. Отметьте для себя, что уже сделано, а что осталось.
- Указали ли вы BIGINT только там, где ожидается более 2,1 млрд записей?
- Проверили ли диапазон значений — signed или unsigned — перед созданием таблицы?
- Учли ли вы, что в PostgreSQL нет UNSIGNED и нужен CHECK?
- Протестировали ли ALTER TABLE на копии базы перед изменением на проде?
- Сравнили ли размер индекса до и после смены типа столбца?
- Выбрали ли DECIMAL для денег с дробной частью вместо BIGINT?
- Хватает ли диска и RAM на сервере под ожидаемый рост таблицы?
Если какой-то пункт пока не выполнен, вернитесь к нужному разделу статьи — там разобрано, как это сделать и на чём чаще всего ошибаются.
Источники
На сайте есть партнёрские ссылки: если вы оформите заказ по ним, мы получим вознаграждение от провайдера. Это не влияет на цену для вас и на место в рейтинге.