Текст и даты: varchar, text, timestamp, interval
Храним строки и работаем со временем — двумя типами данных, которые есть в каждой таблице.
timestamp with time zone (timestamptz) — тип для момента времени, который PostgreSQL хранит в UTC и корректно сравнивает между часовыми поясами.
Строки: varchar, char, text
Для текста есть три типа, но на практике выбор простой.
| Тип | Когда брать |
varchar(n) | строка с ограничением длины (например, код страны varchar(2)) |
text | строка любой длины — в PostgreSQL это самый частый выбор |
char(n) | строка фиксированной длины, дополняется пробелами; используется редко |
Важная особенность PostgreSQL: text и varchar работают одинаково быстро. Ограничение длины — это про валидацию данных, а не про производительность. Если ограничение не нужно, смело берите text.
Дата и время
Типов для времени несколько, и путать их опасно.
| Тип | Что хранит |
date | только дату: 2026-06-14 |
time | только время суток: 14:30:00 |
timestamp | дату и время без часового пояса |
timestamptz | момент времени с учётом пояса (хранится в UTC) |
interval | промежуток: «3 дня», «2 часа 30 минут» |
Практическое правило: для событий («когда создан заказ», «время входа») почти всегда берите timestamptz. Он избавляет от боли с часовыми поясами: что бы вы ни вставили, внутри хранится UTC, а на вывод приводится к поясу сессии.
Арифметика дат и interval
Со временем в PostgreSQL можно складывать и вычитать. Разность двух дат даёт interval, а к дате можно прибавить интервал.
-- Текущий момент
SELECT now();
-- Через сколько истечёт подписка на 30 дней
SELECT now() + INTERVAL '30 days' AS expires_at;
-- Сколько дней между двумя датами
SELECT DATE '2026-06-14' - DATE '2026-06-01' AS days; -- 13
now() возвращает текущий момент как timestamptz. Конструкция INTERVAL '30 days' читается как естественный язык — можно писать '2 hours', '1 year 6 months' и так далее.
Практика: фильтр по дате в песочнице
Даты как строки в формате ГГГГ-ММ-ДД отлично сортируются и сравниваются. Переносимый пример — запустите и поменяйте границу.
CREATE TABLE events (
id INTEGER PRIMARY KEY,
title TEXT,
day TEXT
);
INSERT INTO events (id, title, day) VALUES
(1, 'Релиз', '2026-03-01'),
(2, 'Конференция', '2026-06-10'),
(3, 'Ретро', '2026-06-20');
SELECT title, day
FROM events
WHERE day >= '2026-06-01'
ORDER BY day;
Вывод:
Конференция|2026-06-10 Ретро|2026-06-20
Формат ГГГГ-ММ-ДД удобен тем, что лексикографический порядок строк совпадает с хронологическим. В реальном PostgreSQL для этого столбца, конечно, лучше тип date, но логика сравнения та же.
Итог
- Для строк по умолчанию берите
text;varchar(n)— когда нужно ограничить длину. timestamptz— лучший выбор для моментов времени, он хранит UTC и спасает от путаницы с поясами.- Разность дат даёт
interval; к дате можно прибавлятьINTERVAL '...'.