PostgreSQL — что это такое и как использовать в корпоративных проектах
PostgreSQL — свободная объектно-реляционная СУБД с открытым исходным кодом, поддерживающая ACID-транзакции, сложные запросы и расширенный стандарт SQL. По данным DB-Engines Ranking за 2025 год, PostgreSQL занимает 4-е место среди всех СУБД в мире и уверенно держит первенство среди open-source решений. Более 63% новых enterprise-проектов в Европе и России выбирают PostgreSQL как основное хранилище данных. Именно PostgreSQL стоит в стеке большинства проектов на Java + Spring Boot: он надёжен, гибок и бесплатен.
Последнее обновление: март 2026
Что такое PostgreSQL и чем он отличается от MySQL
PostgreSQL создан в 1986 году в Калифорнийском университете Беркли и развивается силами мирового сообщества уже 38 лет. Его нередко называют «самой продвинутой open-source СУБД» — и не зря.
Ключевые отличия от MySQL и других реляционных баз:
- Полное соответствие ACID — данные либо сохранены целиком, либо не сохранены вообще. Никаких полузаписанных строк.
- Расширенные типы данных — нативные JSON/JSONB, массивы, геопространственные типы (PostGIS), UUID, hstore.
- Параллельные запросы — начиная с версии 9.6, PostgreSQL умеет выполнять один SELECT сразу на нескольких ядрах ЦПУ.
- Оконные функции и CTE — сложная аналитика прямо в SQL, без выгрузки в приложение.
- Расширения — PostGIS (геоданные), pg_trgm (нечёткий поиск), TimescaleDB (временные ряды), pgvector (AI-поиск по векторам).
MySQL исторически быстрее на простых SELECT из одной таблицы, но проигрывает PostgreSQL на сложных JOIN, аналитических запросах и при работе с JSON. Для большинства enterprise-проектов разница в скорости несущественна, а богатство функций PostgreSQL перевешивает.
Установка PostgreSQL: с нуля за 10 минут
Официальный репозиторий PGDG — единственный правильный способ установить свежую версию на Ubuntu/Debian. Системный пакет (apt install postgresql) обычно отстаёт на 1–2 мажорные версии.
# Добавляем официальный репозиторий
sudo sh -c 'echo "deb https://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
sudo apt-get update
# Устанавливаем PostgreSQL 16
sudo apt-get install postgresql-16
# Проверяем статус
sudo systemctl status postgresql
После установки PostgreSQL автоматически запускается на порту 5432 и создаёт системного пользователя postgres. Первое подключение:
sudo -u postgres psql
Важный момент для настройки PostgreSQL под production: по умолчанию СУБД выделяет всего 128 МБ под shared_buffers. Для сервера с 8 ГБ RAM рекомендуется установить shared_buffers = 2GB, а effective_cache_size = 6GB. Эти параметры задаются в файле /etc/postgresql/16/main/postgresql.conf. Правильная настройка ускоряет типовые запросы в 3–5 раз без изменения кода приложения.
SQL в PostgreSQL: возможности сверх стандарта
PostgreSQL поддерживает стандарт SQL:2016 практически полностью — это редкость среди СУБД. Несколько возможностей, которые реально ускоряют разработку:
UPSERT (INSERT … ON CONFLICT): атомарная вставка-или-обновление в одной команде, без гонки условий. В MySQL аналог — INSERT ... ON DUPLICATE KEY UPDATE, но семантика отличается.
INSERT INTO devices (id, last_seen, status)
VALUES (42, NOW(), 'online')
ON CONFLICT (id) DO UPDATE
SET last_seen = EXCLUDED.last_seen,
status = EXCLUDED.status;
Оконные функции: ранжирование, нарастающий итог, скользящее среднее — прямо в SQL. В нашем проекте по мониторингу GPS-трекеров оконные функции сократили объём кода на бэкенде на 40%: то, что раньше считалось в Java-цикле, теперь делает один запрос.
SELECT device_id,
recorded_at,
speed,
AVG(speed) OVER (
PARTITION BY device_id
ORDER BY recorded_at
ROWS BETWEEN 4 PRECEDING AND CURRENT ROW
) AS avg_speed_5min
FROM telemetry_points
WHERE recorded_at > NOW() - INTERVAL '1 hour';
Для разработки REST API особенно полезна возможность возвращать агрегированный JSON прямо из запроса — функции json_agg() и row_to_json() позволяют не делать лишние round-trip между БД и приложением.
Индексы в PostgreSQL: ускоряем запросы на 90%
PostgreSQL поддерживает 6 типов индексов. В большинстве проектов используют 3:
- B-tree — по умолчанию. Подходит для равенства и диапазонов (
=,<,BETWEEN). Покрывает 90% задач. - GIN — для полнотекстового поиска, массивов и JSONB. Если нужно искать по содержимому JSON-документа или по тегам, GIN в 10–50 раз быстрее B-tree.
- BRIN — блочный индекс для таблиц с сотнями миллионов строк, упорядоченных по времени (логи, телеметрия). Занимает в 100 раз меньше места, чем B-tree.
Частая ошибка — создавать индекс на каждую колонку. Каждый индекс замедляет INSERT/UPDATE примерно на 5–15%. В одном из наших проектов (система учёта 1 млн+ устройств) удаление 11 избыточных индексов ускорило запись телеметрии с 8 000 до 14 000 строк/сек.
Команда для поиска неиспользуемых индексов:
SELECT relname, indexrelname, idx_scan
FROM pg_stat_user_indexes
WHERE idx_scan = 0
ORDER BY relname;
Подробнее о проектировании структуры данных читайте в нашем материале о разработке систем управления базами данных.
JSON в PostgreSQL: документная модель без отдельной СУБД
JSONB (бинарный JSON) в PostgreSQL — полноценная альтернатива MongoDB для большинства сценариев. Разница между JSON и JSONB: первый хранит текст как есть, второй парсит при записи и хранит в оптимизированном бинарном формате.
JSONB позволяет:
- Создавать GIN-индексы по любому пути внутри документа
- Делать
SELECTпо вложенным полям через операторы->и->> - Обновлять отдельные ключи командой
jsonb_set()без перезаписи всего документа - Хранить схемы с переменной структурой рядом со строго типизированными данными
В проекте на JMIX мы используем JSONB для хранения конфигураций устройств (у каждого трекера свой набор параметров). Это избавило от необходимости добавлять MongoDB в стек: PostgreSQL справляется с 50 000 документных записей/сек на обычном SSD-сервере.
Docker и PostgreSQL: разворачиваем за 2 команды
Для разработки и тестирования удобнее всего запускать PostgreSQL в Docker. Официальный образ весит 380 МБ и поднимается за 8–12 секунд:
# Запуск PostgreSQL в Docker
docker run -d \
--name postgres-dev \
-e POSTGRES_PASSWORD=secret \
-e POSTGRES_DB=myapp \
-p 5432:5432 \
-v pgdata:/var/lib/postgresql/data \
postgres:16
# Проверка
docker exec -it postgres-dev psql -U postgres -d myapp
Для production-окружения используем docker-compose с настройками healthcheck и restart-политикой. PostgreSQL в Docker на наших проектах прошёл нагрузочные тесты: 5 000 concurrent connections, 20 000 транзакций/сек на сервере с 16 ГБ RAM — без деградации производительности.
PostgreSQL UPDATE: как правильно обновлять данные
Команда UPDATE в PostgreSQL работает немного иначе, чем кажется. При обновлении строки PostgreSQL физически создаёт новую версию строки и помечает старую как удалённую. Это называется MVCC (Multi-Version Concurrency Control) — механизм, обеспечивающий параллельное чтение без блокировок.
Следствие: таблицы с частыми UPDATE «раздуваются» со временем. Решение — регулярный автовакуум (работает автоматически) и ручной VACUUM FULL для таблиц с высокой частотой обновлений.
Массовое обновление 1 млн строк в одной транзакции — плохая идея: это создаёт огромный WAL-файл и блокирует таблицу. Лучше разбить на батчи по 10 000 строк с небольшой паузой между ними:
DO $$
DECLARE
batch_size INT := 10000;
offset_val INT := 0;
rows_updated INT;
BEGIN
LOOP
UPDATE devices SET status = 'inactive'
WHERE id IN (
SELECT id FROM devices
WHERE last_seen < NOW() - INTERVAL '30 days'
AND status != 'inactive'
LIMIT batch_size
);
GET DIAGNOSTICS rows_updated = ROW_COUNT;
EXIT WHEN rows_updated = 0;
PERFORM pg_sleep(0.1);
END LOOP;
END $$;
Такой подход позволяет обновить 10 млн строк без блокировки сервиса — операция идёт фоном за 15–20 минут вместо одной тяжёлой транзакции на 2–3 часа.
Репликация в PostgreSQL: надёжность для production
PostgreSQL поддерживает потоковую репликацию (streaming replication) «из коробки» — с версии 9.0. Схема: один первичный узел (primary) принимает записи, один или несколько реплик (standby) синхронизируются в реальном времени.
Два режима:
- Асинхронная — запись подтверждается сразу, реплика догоняет с задержкой до 1–2 сек. Подходит для 95% случаев.
- Синхронная — транзакция фиксируется только после подтверждения от реплики. Нулевая потеря данных при сбое, но +20–40% к latency записи.
В enterprise-проектах типичная схема: 1 primary + 1 синхронная standby (disaster recovery) + 1–2 асинхронные реплики для чтения. Такая топология обеспечивает RPO = 0 (нет потери данных) и RTO < 30 сек (восстановление за полминуты).
PostgreSQL в Spring Boot проектах: наш подход
В большинстве наших проектов стек — Java 17, Spring Boot, JMIX и PostgreSQL. Настройка занимает около 15 минут:
# application.properties
spring.datasource.url=jdbc:postgresql://localhost:5432/myapp
spring.datasource.username=appuser
spring.datasource.password=${DB_PASSWORD}
spring.datasource.hikari.maximum-pool-size=20
spring.datasource.hikari.connection-timeout=3000
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.hibernate.ddl-auto=validate
Несколько правил, которых мы придерживаемся в production:
- HikariCP pool size = (ядра ЦПУ × 2) + диски. Для 4-ядерного сервера — 10–12 соединений. Больше не даёт прироста, только увеличивает нагрузку на PostgreSQL.
- Liquibase для миграций — никакого
ddl-auto=updateв production. Все изменения схемы — через changelog-файлы, с возможностью отката. - EXPLAIN ANALYZE для медленных запросов — если запрос выполняется дольше 100 мс, смотрим план через explain и добавляем нужный индекс. Это решает 80% проблем с производительностью.
- pgBouncer перед PostgreSQL — пул соединений на уровне транзакций. При 500+ одновременных пользователях сокращает нагрузку на СУБД в 3–5 раз.
Если вы планируете построить систему на PostgreSQL «с нуля» или перенести legacy на современный стек — мы занимаемся разработкой программного обеспечения под задачи бизнеса любой сложности.
Часто задаваемые вопросы о PostgreSQL
Чем PostgreSQL лучше MySQL для enterprise-проектов?
PostgreSQL точнее соответствует стандарту SQL, поддерживает JSONB, оконные функции, нативную репликацию и расширения (PostGIS, pgvector). MySQL быстрее на простых запросах к одной таблице, но для сложной аналитики и высоконагруженных систем PostgreSQL выигрывает. Большинство крупных компаний (Instagram, GitLab, Shopify) перешли с MySQL на PostgreSQL в период роста нагрузки.
Сколько данных выдерживает PostgreSQL?
Теоретический предел таблицы — 32 ТБ, базы данных — не ограничен. Практически — Instagram хранит в PostgreSQL петабайты данных с 2011 года. При правильном партиционировании и индексировании PostgreSQL уверенно обрабатывает таблицы с миллиардами строк.
Можно ли использовать PostgreSQL вместо MongoDB?
Для большинства задач — да. JSONB в PostgreSQL покрывает 90% сценариев использования MongoDB: документное хранение, гибкая схема, индексируемые JSON-поля. Плюс вы получаете транзакции, JOIN и SQL. MongoDB остаётся актуальным для горизонтального шардирования с сотнями узлов — это то, что PostgreSQL не умеет «из коробки».
Как PostgreSQL работает с высокой нагрузкой?
PostgreSQL обрабатывает 50 000–100 000 транзакций/сек на современном железе (24 ядра, NVMe SSD). Для масштабирования читающих запросов используется репликация + pgBouncer. Для горизонтального масштабирования записи — Citus (расширение для шардирования). В наших проектах PostgreSQL выдерживал пиковую нагрузку 15 000 запросов/сек без деградации.
Сколько стоит поддержка PostgreSQL-проекта?
Лицензия бесплатна — это open-source. Стоимость поддержки зависит от сложности системы: для небольших приложений (до 50 ГБ данных) — от 5 000 руб./мес, для высоконагруженных систем с репликацией — от 25 000 руб./мес. Мы предлагаем поддержку от 5% стоимости разработки в месяц.