PostgreSQL — что это такое и как использовать в корпоративных проектах

17.03.2026

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:

  1. HikariCP pool size = (ядра ЦПУ × 2) + диски. Для 4-ядерного сервера — 10–12 соединений. Больше не даёт прироста, только увеличивает нагрузку на PostgreSQL.
  2. Liquibase для миграций — никакого ddl-auto=update в production. Все изменения схемы — через changelog-файлы, с возможностью отката.
  3. EXPLAIN ANALYZE для медленных запросов — если запрос выполняется дольше 100 мс, смотрим план через explain и добавляем нужный индекс. Это решает 80% проблем с производительностью.
  4. 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% стоимости разработки в месяц.