Все материалы
Продуктовая аналитикагайдстарт

Типы данных SQL и PostgreSQL: таблица с примерами

Таблица типов данных PostgreSQL с примерами: integer и bigint, NUMERIC и DOUBLE, VARCHAR и TEXT, дата и время, UUID, JSONB. Как выбрать тип и чем отличаются MySQL и ClickHouse.

КейсПрактика31 октября 2026 г.9 мин

Тип данных — это обещание столбца: здесь лежат целые числа, здесь деньги с копейками, здесь момент во времени. От типа зависит, что база разрешит записать, как она сравнит значения, отсортирует и посчитает сумму. Ниже — сводная таблица типов PostgreSQL с примерами, разбор групп, которые чаще всего путают (NUMERIC и DOUBLE, VARCHAR и TEXT, SERIAL и IDENTITY), как посмотреть типы столбцов в своей базе и чем названия отличаются в MySQL, SQL Server и ClickHouse.

Коротко

  • Целые числа и идентификаторы — integer или bigint, если строк может стать больше двух миллиардов.
  • Деньги — numeric(12, 2): точные десятичные дроби. double precision — для измерений, где важна скорость, а не копейка.
  • Строки — text или varchar(n). В PostgreSQL они одинаково быстрые, n нужен только как ограничение длины.
  • Моменты времени — timestamptz, календарные дни — date.
  • Новый ключ-счётчик — bigint generated always as identity вместо устаревшего serial.

Сводная таблица типов PostgreSQL

В таблице — типы, которые встречаются в рабочих базах продукта. PostgreSQL знает больше (геометрию, сетевые адреса, диапазоны), но аналитик сталкивается с ними редко.

Основные типы данных PostgreSQL
ГруппаТипРазмерДиапазон или смыслПример
Целыеsmallint2 байта−32 768 … 32 767возраст, номер месяца
Целыеinteger, int4 байта≈ ±2,1 млрдколичество, id небольшой таблицы
Целыеbigint8 байт≈ ±9,2 × 10¹⁸id событий и заказов
Точные дробныеnumeric(p, s), decimalпеременныйдо 131 072 цифр до запятойсуммы денег: numeric(12, 2)
Приближённыеreal4 байта≈ 6 значащих цифрпоказания датчиков
Приближённыеdouble precision8 байт≈ 15 значащих цифркоординаты, оценки модели
Счётчикиserial, bigserial4 и 8 байтinteger или bigint с последовательностьюстарый способ задать id
Строкиtextпеременныйбез ограничения длиныкомментарий, название
Строкиvarchar(n)переменныйне длиннее n символовкод страны varchar(2)
Строкиchar(n)n символовдополняется пробелами до nпочти не нужен
Логическийboolean1 байтtrue, false, nullфлаг is_paid
Дата и времяdate4 байтадень без временидата регистрации
Дата и времяtimestamp8 байтдата и время без поясавремя по договорённому поясу
Дата и времяtimestamptz8 байтмомент во времени (UTC)время события
Дата и времяinterval16 байтдлительность3 days 04:00:00
Идентификаторыuuid16 байт128-битный идентификаторid из внешней системы
ДокументыjsonbпеременныйJSON в разобранном видесвойства события
Массивыinteger[], text[]переменныйсписок значений одного типатеги товара

Целые числа: integer или bigint

Для подсчётов и небольших справочников хватает integer. Для идентификаторов событий, заказов и всего, что растёт каждый день, берите bigint сразу. Переполнение integer — не теория: на 2 147 483 648-й строке вставка падает с ошибкой «integer out of range», а поменять тип у таблицы в миллиарды строк — это часы блокировки.

Аналитику переполнение встречается и в расчётах: сумма большого числа значений integer в PostgreSQL возвращается как bigint, но умножение двух integer остаётся integer и может не поместиться. Если перемножаете большие счётчики, приведите один множитель к bigint или numeric.

NUMERIC против DOUBLE PRECISION

double precision хранит число в двоичной дроби, и большинство десятичных дробей в ней представимы только приблизительно. Поэтому 0,1 + 0,2 в double не равно 0,3 — разница в шестнадцатом знаке. На одной операции это незаметно, на сумме миллиона платежей копейки расходятся с бухгалтерией.

numeric хранит десятичные цифры точно. Он медленнее на тяжёлых вычислениях, но для денег, процентов комиссии и всего, что сверяют с внешним отчётом, выбора нет. Запись numeric(12, 2) значит: всего до 12 цифр, из них 2 после запятой.

Результат
double_equalnumeric_equal
falsetrue
0,1 + 0,2 в двух числовых типах
select
  0.1::double precision + 0.2::double precision = 0.3 as double_equal,
  0.1::numeric(10, 2) + 0.2::numeric(10, 2) = 0.3     as numeric_equal;
Тип money лучше не использовать

В PostgreSQL есть тип money, но знак валюты и формат он берёт из локали сервера: на одном сервере сумма выйдет с долларом, на другом — с рублём. Для денег надёжнее numeric и отдельный столбец с кодом валюты.

VARCHAR, TEXT и CHAR

В PostgreSQL text и varchar(n) хранятся одинаково и работают с одной скоростью. Документация прямо говорит, что разницы в производительности между ними нет. varchar(n) нужен, когда ограничение длины — часть правил данных: код страны из двух букв, номер телефона. varchar без числа — то же самое, что text.

У ограничения есть ловушка. Вставка слишком длинной строки в varchar(3) падает с ошибкой, а явное приведение 'abcd'::varchar(3) молча обрезает строку до abc. Если очищаете данные через CAST, длинные значения потеряют хвост без предупреждения.

char(n) дополняет строку пробелами до длины n. При сравнении и склейке PostgreSQL эти пробелы игнорирует, а в выгрузке и при подсчёте байт они есть. Новых причин выбирать char почти нет: ограничение длины даёт varchar(n) без сюрпризов с пробелами.

PostgreSQL only: как ведут себя varchar(n) и char(n)
select
  'abcd'::varchar(3)        as cast_truncates,   -- abc
  'ab'::char(5) = 'ab'      as char_equal,       -- true
  length('ab'::char(5))     as char_length,      -- 2
  octet_length('ab'::char(5)) as char_bytes;     -- 5

-- А вставка не обрезает, а падает:
-- insert into t (code) values ('abcd');
-- ERROR: value too long for type character varying(3)

SERIAL и IDENTITY: автоинкремент

serial — не настоящий тип, а сокращение: столбец integer, последовательность и значение по умолчанию nextval(…). Так id задавали годами, и вы увидите serial во многих старых схемах.

С PostgreSQL 10 стандартный способ — generated always as identity. Он описан в стандарте SQL, последовательность принадлежит столбцу, и случайно записать в id своё значение не выйдет. Для новой таблицы пишите id bigint generated always as identity primary key. Подробнее — в статье про CREATE TABLE.

Дата и время

Главное различие — timestamp и timestamptz. Первый хранит показания часов без пояса, второй — момент во времени, который показывается в поясе сессии. Для событий почти всегда нужен timestamptz, для дат договоров и рождений — date. Разница и перевод между поясами подробно разобраны в статье про TIMESTAMP в PostgreSQL, а группировка по неделям и месяцам — в статье про DATE_TRUNC.

BOOLEAN, UUID, JSONB и массивы

boolean хранит true, false или null. Считать долю удобно через avg(flag::int) или count(*) filter (where flag): сложение булевых значений напрямую в PostgreSQL не работает.

uuid — 128-битный идентификатор, его удобно генерировать вне базы. С PostgreSQL 13 функция gen_random_uuid() встроена. Хранить uuid в text можно, но столбец будет вдвое больше и сравнения медленнее.

jsonb хранит JSON в разобранном виде: поиск по ключам быстрый, по нему строят индексы. Старый json хранит текст как есть и подходит только для логов, которые никто не разбирает. Массивы (text[]) хороши для коротких списков вроде тегов. Если элементы массива нужно соединять с другими таблицами, лучше отдельная таблица.

Как посмотреть типы столбцов

В psql: команда \d payments выводит столбцы таблицы, их типы, ограничения и индексы. В любом клиенте — запрос к стандартному представлению information_schema.columns. Он работает и в PostgreSQL, и в DuckDB, на котором устроена песочница, но названия типов движки пишут по-своему.

Тип любого выражения покажет функция pg_typeof(…): например, pg_typeof(sum(amount)). Удобно, когда непонятно, почему деление вернуло целое число.

Как разные движки называют одни и те же типы
СтолбецDuckDB (песочница)PostgreSQL
payments.payment_idINTEGERinteger
payments.paid_atDATEdate
payments.amountDECIMAL(10,2)numeric
payments.planVARCHARcharacter varying или text
DuckDB и PostgreSQL: типы столбцов учебной базы
select table_name, column_name, data_type
from information_schema.columns
where table_name in ('users', 'payments')
order by table_name, ordinal_position;

Типы в других СУБД

Стандарт SQL задаёт общие названия, но каждая СУБД добавляет свои. Если запрос или схема переезжает, проверьте прежде всего деньги, строки и время.

Соответствие типов
СмыслPostgreSQLMySQLSQL ServerClickHouse
Целое 4 байтаintegerintintInt32
Целое 8 байтbigintbigintbigintInt64
Деньгиnumeric(12,2)decimal(12,2)decimal(12,2)Decimal(12,2)
Строкаtext, varchar(n)varchar(n), textnvarchar(n)String
Логическийbooleantinyint(1)bitBool
ДатаdatedatedateDate
Момент времениtimestamptztimestampdatetimeoffsetDateTime('пояс')
JSONjsonbjsonnvarchar(max)JSON, String

Как выбрать тип: чеклист

  • Будет ли значение участвовать в арифметике? Если да — число, а не текст с цифрами. Номер телефона и почтовый индекс — текст: с ними не считают, и у них бывают ведущие нули.
  • Нужна ли точность до копейки? Да — numeric. Нет, и важна скорость на миллионах строк — double precision.
  • Может ли таблица вырасти больше двух миллиардов строк? Да — bigint для ключей.
  • Есть ли у значения правило длины? Да — varchar(n) или ограничение check. Нет — text.
  • Это момент или календарный день? Момент — timestamptz, день — date.

Частые вопросы

Чем varchar отличается от text в PostgreSQL?

Только тем, что у varchar(n) есть предел длины. Хранение и скорость одинаковые.

Какой тип выбрать для денег?

numeric с двумя знаками после запятой, например numeric(12, 2). Не double precision и не money.

Сколько символов можно записать в text?

Ограничения длины нет, предел — около 1 ГБ на значение.

Что такое serial в PostgreSQL?

Столбец integer с собственной последовательностью и значением по умолчанию. В новых таблицах вместо него используют generated always as identity.

Как изменить тип столбца?

alter table … alter column … type новый_тип using выражение;. На большой таблице команда переписывает её целиком, поэтому её планируют заранее.

Почему 7 / 2 в PostgreSQL даёт 3?

Деление двух целых — целочисленное. Приведите одно из чисел к numeric. Разбор этой и других ловушек приведения — в статье про CAST.

Типы на практике удобнее всего проверить на учебной базе в песочнице. Курс «SQL с нуля» начинается с модуля о том, как устроены таблицы и их столбцы.

Продолжить чтение
Вся библиотека