TSKLab и базы данных: PostgreSQL против MongoDB в реальных проектах

TSKLab и базы данных: PostgreSQL против MongoDB в реальных проектах

Когда ко мне приходят с вопросом «что круче — PostgreSQL или MongoDB», я всегда прошу показать модель данных. Потому что выбор базы — это не голосование за бренд, а инженерное решение, которое определяется тем, как устроены ваши сущности, какие запросы будут ходить и насколько критична целостность. В реальных системах PostgreSQL чаще выигрывает там, где важны согласованность, сложные связи и предсказуемость, а MongoDB — там, где схема часто меняется, данные похожи на документы и нужно быстро развивать продукт.

Когда сравнение вообще имеет смысл

Если задача сводится к одному из сценариев ниже, выбор базы данных влияет на архитектуру очень сильно. Пропускать этот анализ — значит закладывать фундамент, который потом придётся перестраивать.

  • есть транзакции, деньги, статусы заказов, склад, биллинг — ошибка в данных здесь стоит реальных потерь, и строгая согласованность выходит на первый план;
  • данные связаны между собой и часто выбираются через JOIN — если у вас десятки таблиц и отчёты строятся на пересечении сущностей, документная модель быстро становится неудобной;
  • продукт активно меняется, а структура сущностей пока нестабильна — на этапе поиска product-market fit миграции схемы могут тормозить разработку;
  • нужно хранить полуструктурированные данные, события, профили, каталоги — здесь документный подход часто выглядит естественнее;
  • важны скорость разработки, масштабирование и удобство поддержки — каждая СУБД даёт эти преимущества в разных контекстах.

Ошибка многих команд в том, что они выбирают СУБД по привычке или потому что «так сейчас модно». На практике правильнее отталкиваться от модели данных, характера запросов и требований к надёжности. Я не раз видел, как проект начинался на MongoDB, а через полгода команда героически переезжала на PostgreSQL, потому что появились жёсткие отчёты и связи, которые в документной модели давались с кровью.

Коротко: в чем философская разница

PostgreSQL — реляционная база данных. Она хорошо работает, когда данные можно разложить по таблицам, связать ключами и описать строгими правилами. Это особенно полезно в системах, где ошибка в данных дорого стоит, а бизнес-логика опирается на непротиворечивость.

MongoDB — документная база данных. Она хранит данные в виде документов, что удобно, когда один объект содержит вложенные поля и структура может отличаться от записи к записи. Такой подход часто ускоряет разработку на старте, потому что не нужно заранее проектировать все связи и нормализовывать каждую сущность.

Но важно понимать: современные версии обеих систем размывают эту границу. PostgreSQL умеет эффективно работать с JSON, а MongoDB поддерживает ACID-транзакции. Поэтому философская разница — это скорее про то, как вы мыслите данные: как набор связанных таблиц или как коллекцию самодостаточных документов.

Простая аналогия

  • PostgreSQL — как аккуратный архив с каталогом, где у каждого документа есть место, правила и связи. Вы всегда знаете, где что лежит, и можете быстро собрать отчёт по нескольким папкам.
  • MongoDB — как набор папок с документами, где каждый файл может быть чуть разным по форме, но его удобно брать целиком. Если вам часто нужен весь документ сразу — это быстро и удобно.

Что важно знать о PostgreSQL

PostgreSQL поддерживает классические типы JSON: json и jsonb, а также механизм jsonpath для эффективной работы с JSON-данными. Это значит, что он давно не только «про таблицы», но и про гибкую работу с полуструктурированными данными. jsonb хранит данные в бинарном формате, что позволяет строить GIN-индексы и выполнять быстрый поиск по содержимому JSON — на практике это работает весьма достойно, хотя и уступает нативной документной модели MongoDB при очень глубокой вложенности и частых изменениях структуры.

Это особенно важно, если команда думает, что PostgreSQL «не умеет документный сценарий». Умеет — просто делает это в рамках реляционной модели, где данные остаются под контролем схемы, ограничений и индексов. Мы в лаборатории не раз использовали jsonb для хранения метаданных или нестабильных атрибутов, и это позволяло избежать лишней СУБД в проекте.

Сильные стороны PostgreSQL

  • Строгая целостность данных — внешние ключи, ограничения CHECK, триггеры дают уверенность, что данные не испортятся случайно.
  • Надёжные транзакции с классической изоляцией — никаких сюрпризов при конкурентном доступе.
  • Сложные запросы и аналитика — оконные функции, CTE, рекурсивные запросы позволяют решать задачи, которые в документных базах требуют громоздких пайплайнов агрегации.
  • JOIN, агрегации, подзапросы — когда данные разнесены по десяткам таблиц, это работает предсказуемо и оптимизируется планировщиком.
  • Хорошая работа с JSON без отказа от SQL — можно комбинировать реляционные и документные подходы в одной базе.
  • Предсказуемость для долгоживущих систем — десятилетиями проверенная стабильность и огромное комьюнити.

Где PostgreSQL особенно хорош

  • интернет-магазины с заказами, оплатами и складскими остатками;
  • CRM и ERP, где всё завязано на связях между сущностями;
  • бухгалтерия и финтех — здесь целостность данных критична;
  • учётные системы с аудитом и историей изменений;
  • сервисы с многошаговыми бизнес-операциями, где состояние должно быть согласованным на каждом шаге;
  • продукты, где важна отчётность и выборки по множеству связей.

Что важно знать о MongoDB

MongoDB ориентирована на документную модель и поддерживает ACID-транзакции для многодокументных операций. Это снимает старый миф о том, что MongoDB годится только для «несерьёзных» данных и не подходит для транзакционных сценариев. Транзакции появились с версии 4.0 и действительно работают, но важно понимать их цену: в высоконагруженных системах они могут стать узким местом, поэтому мы всегда стараемся проектировать документы так, чтобы изменения затрагивали один документ, и транзакции требовались как можно реже.

Наличие транзакций не отменяет главного: документная модель лучше всего раскрывается там, где объект естественно хранится целиком, а доступ к нему идёт чаще как к единице, чем как к набору связанных таблиц. Если вы начинаете массово использовать ссылки между коллекциями и эмулировать JOIN через $lookup, стоит задуматься — возможно, вам нужна реляционная база.

Сильные стороны MongoDB

  • гибкая схема — можно добавлять новые поля без миграций, что ускоряет итерации;
  • удобная работа с вложенными структурами — массивы, подобъекты хранятся прямо в документе;
  • быстрое изменение модели данных — не нужно писать ALTER TABLE и блокировать таблицы;
  • хороша для событий, контента, профилей, каталогов — там, где структура от документа к документу может различаться;
  • удобна, когда один запрос обычно читает весь документ целиком — минимум обращений к диску.

Где MongoDB особенно хороша

  • каталоги с разной структурой карточек — например, у одежды есть размеры, у электроники — характеристики;
  • пользовательские профили с произвольным набором полей;
  • контентные платформы, где статьи, видео и посты имеют разную метаинформацию;
  • телеметрия и события — потоковая запись разнородных данных;
  • прототипы и быстро меняющиеся продукты, где схема ещё не устоялась;
  • микросервисы, где каждый сервис хранит свой автономный документ и не требует сложных связей с другими сервисами.

Сравнение PostgreSQL и MongoDB по ключевым критериям

Критерий PostgreSQL MongoDB
Модель данных Реляционная, таблицы и связи Документная, JSON-подобные документы
Схема Строгая, хорошо контролируемая Гибкая, легко менять
Транзакции Классический сильный сценарий Поддерживаются многодокументные ACID-транзакции
JOIN и сложные связи Сильная сторона Обычно стараются избегать
JSON json, jsonb, jsonpath Нативная документная модель
Отчётность и аналитика Очень сильная Обычно слабее для сложных отчётов
Быстрая эволюция схемы Средне Очень хорошо
Предсказуемость для бизнеса Высокая Высокая, если правильно спроектировать модель

Эта таблица не должна восприниматься как чек-лист «галочек». Например, поддержка JSON в PostgreSQL не делает его документной базой — она даёт возможность точечно применять документный подход внутри реляционной модели. А транзакции в MongoDB не превращают её в замену PostgreSQL для финансового учёта — они решают конкретную задачу, но с оговорками по производительности.

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

Выбирайте PostgreSQL, если:

  • у вас есть строгие бизнес-правила, нарушение которых чревато финансовыми потерями;
  • данные связаны между собой, и эти связи активно используются в запросах;
  • важны транзакции с высоким уровнем изоляции и целостность при конкурентном доступе;
  • нужен сложный SQL — отчёты, аналитика, выборки по нескольким таблицам;
  • предстоит регулярная отчётность, которую удобно строить на SQL, а не на пайплайнах агрегации;
  • проект будет жить долго и развиваться поэтапно — строгая схема дисциплинирует команду и упрощает поддержку.

Выбирайте MongoDB, если:

  • структура данных часто меняется, и вы не хотите постоянно гонять миграции;
  • объекты удобно хранить целиком, и типичный запрос — получить документ по ID;
  • много вложенных полей, которые не нужно часто фильтровать по отдельности;
  • схема ещё не устоялась, и продукт находится в стадии активных экспериментов;
  • важна скорость запуска и частые изменения модели — отсутствие необходимости синхронизировать схему с кодом ускоряет итерации;
  • документная модель соответствует предметной области — например, контент, события, профили.

Практический разбор сценариев

1. Интернет-магазин

Для каталога товаров MongoDB может выглядеть заманчиво: у разных категорий разные свойства, и хранить их в документах удобно. Мы сами так делали в одном проекте — миллионы товаров, у каждой категории свой набор атрибутов, всё быстро читалось. Но как только появились заказы, оплаты, резервы, скидки, возвраты и отчёты по продажам, PostgreSQL стал надёжнее. Сложные фильтры с пересечением свойств в MongoDB требовали либо денормализации, либо выноса поиска в Elasticsearch, что добавляло сложности.

Практический вывод:

  • каталог можно хранить гибко — MongoDB или даже PostgreSQL с jsonb;
  • транзакционный контур (заказы, платежи, остатки) лучше строить на PostgreSQL;
  • смешанный подход часто оказывается лучшим, но требует чёткого разделения ответственности и синхронизации данных.

2. Сервис бронирования

Тут важны конкурирующие операции, блокировки, статусы, отмены и аудит. Когда два пользователя одновременно пытаются забронировать последний номер, нужна гарантия, что только один получит подтверждение. PostgreSQL с его блокировками строк (SELECT FOR UPDATE) и транзакционной изоляцией даёт эту гарантию предсказуемо. MongoDB тоже поддерживает транзакции, но в сценариях с высоким конкурентным доступом реляционная модель с блокировками на уровне строк обычно работает прозрачнее и не требует дополнительных ухищрений. Плюс аудит и история изменений естественно ложатся на реляционные таблицы.

3. Продукт с пользовательскими анкетами

Если у одних пользователей 10 полей, у других 50, а набор полей постоянно меняется, MongoDB может дать удобную модель — просто добавляете новые поля в документ, и всё. Но если потом понадобится сложная фильтрация, сегментация и аналитика по этим полям, PostgreSQL с jsonb и GIN-индексами тоже может закрыть задачу без перехода на другую СУБД. Мы не раз применяли такой гибрид внутри одного PostgreSQL: основные поля хранили в колонках, а нестабильные — в jsonb. Это давало и строгость, и гибкость, но требовало дисциплины в именовании ключей, чтобы не превратить JSON в свалку.

4. Событийная система

Если вы пишете пользовательские события, клики, телеметрию или логи, MongoDB часто удобна как хранилище документов — запись быстрая, структура события может быть разной. Но при высоких требованиях к аналитике PostgreSQL тоже стоит рассмотреть, особенно если данные потом агрегируются SQL-запросами. В нашей практике для сбора событий мы использовали MongoDB, а для построения дашбордов переливали агрегированные данные в PostgreSQL или ClickHouse, потому что сложные аналитические запросы в MongoDB требуют аккуратности с пайплайнами агрегации и могут уступать по производительности оптимизированному SQL.

Типовые ошибки при выборе

  • Выбирать MongoDB только потому, что «там нет схемы». Гибкость требует дисциплины: без контроля имена полей начинают различаться, и данные превращаются в свалку, с которой потом сложно работать.
  • Брать PostgreSQL и пытаться использовать его как хаотичное хранилище без нормализации и ограничений — тогда теряются все преимущества реляционной модели, а поддержка становится кошмаром.
  • Переоценивать гибкость MongoDB и недооценивать цену сложных связей — когда связей много, а вы пытаетесь их эмулировать через $lookup, производительность и читаемость кода страдают.
  • Ставить PostgreSQL в роль «просто хранилища JSON» и терять его сильные стороны — если всё класть в jsonb и не использовать нормализацию, то проще взять документную базу.
  • Выбирать СУБД до того, как описаны реальные сценарии чтения и записи — без этого любое решение гадание.

Что проверить до старта разработки

Чек-лист для команды

  • Какие сущности у системы есть на самом деле? — нарисуйте модель, даже если она приблизительная.
  • Какие данные меняются вместе, а какие — независимо? — это подскажет, где нужны транзакции.
  • Нужны ли транзакции между несколькими объектами? — если да, PostgreSQL часто безопаснее.
  • Будут ли сложные отчёты и фильтры? — для аналитики SQL обычно удобнее.
  • Как часто меняется схема? — если каждую неделю, MongoDB даст фору по скорости разработки.
  • Сколько данных будет читаться целиком, а сколько — по связям? — это влияет на выбор между документом и JOIN.
  • Нужна ли гибридная модель? — возможно, часть данных хранить в одной базе, часть в другой, или использовать jsonb внутри PostgreSQL.

Если на большинство вопросов ответы связаны с целостностью, отчётностью и множеством связей — PostgreSQL почти наверняка безопаснее. Если ключевой ответ — «схема ещё не устоялась, а продукт быстро меняется» — MongoDB может дать выигрыш на старте, но заложите время на возможный рефакторинг, если требования усложнятся.

Гибридный подход: когда не нужно выбирать одну базу

В реальных проектах часто не нужно сводить всё к одной СУБД. Это нормальная инженерная практика, которую мы в TSKLab применяем регулярно. Например:

  • PostgreSQL для заказов, платежей и пользователей — всё, что требует строгой согласованности;
  • MongoDB для гибких профилей, событий или контентных блоков — где важна скорость изменения схемы;
  • PostgreSQL как основное хранилище, а jsonb — для части нестабильных атрибутов, чтобы не плодить СУБД без крайней необходимости.

Такой подход даёт баланс между надёжностью и гибкостью, но требует дисциплины в архитектуре. Главное — не дублировать одни и те же данные в разных местах без ясной причины и не пытаться делать распределённые транзакции между базами. Каждый сервис должен владеть своим хранилищем, а синхронизация — быть асинхронной и отказоустойчивой.

Рекомендация TSKLab для практики

Если проект новый и предметная область понятна, чаще всего разумно начинать с PostgreSQL. Он закрывает больше сценариев, лучше подходит для строгой бизнес-логики и оставляет запас по гибкости за счёт JSON-механизмов. Когда мы стартуем новый сервис в лаборатории, то по умолчанию рассматриваем PostgreSQL, а MongoDB — только если документная модель явно напрашивается.

MongoDB стоит выбирать осознанно, когда документная модель реально соответствует задаче, а не потому, что она кажется современнее. В хорошо спроектированном продукте MongoDB отлично работает, но она не заменяет реляционное мышление там, где требуется строгий учёт связей. Если вы всё же выбрали MongoDB, сразу продумайте стратегию индексов и шардирования — без этого с ростом данных можно получить серьёзные проблемы с производительностью.

Итог

PostgreSQL и MongoDB решают разные задачи, а не конкурируют на уровне «сильнее/слабее». PostgreSQL лучше там, где важны целостность, связи, транзакции и аналитика. MongoDB сильнее в гибких документных сценариях, где модель данных быстро меняется и объект удобно хранить как единое целое.

Правильный выбор делается не по популярности технологии, а по тому, как реально устроены данные, запросы и бизнес-риски. Потратьте время на анализ модели до написания кода — это сэкономит месяцы переделок в будущем.

FAQ

Что выбрать для стартапа: PostgreSQL или MongoDB?

Если модель данных ещё не зафиксирована и продукт быстро меняется, MongoDB может быть удобнее на раннем этапе — вы быстрее проверяете гипотезы без миграций. Но как только появляются платежи, заказы или сложные связи, лучше сразу заложить PostgreSQL, иначе потом придётся переписывать значительную часть кода. Если сомневаетесь, начните с PostgreSQL и используйте jsonb для нестабильных частей — это даст гибкость без дополнительной СУБД.

Можно ли хранить JSON в PostgreSQL?

Да, PostgreSQL поддерживает json и jsonb, а также jsonpath для запросов к JSON-данным. jsonb хранит данные в бинарном виде и позволяет строить GIN-индексы для быстрого поиска. Мы активно используем это для хранения метаданных или атрибутов, которые не нужно часто фильтровать по отдельности. Но если вы планируете делать сложные запросы по глубоко вложенным полям, лучше сразу вынести их в отдельные колонки или использовать специализированные индексы.

Подходит ли MongoDB для транзакционных систем?

Да, MongoDB поддерживает многодокументные ACID-транзакции. Но для систем с большим количеством связей и отчётов PostgreSQL часто удобнее, потому что его транзакционная модель отточена десятилетиями, а SQL даёт выразительные средства для сложных выборок. В высоконагруженных системах мы стараемся минимизировать использование транзакций в MongoDB, проектируя документы так, чтобы изменения были атомарны в пределах одного документа.

Что проще сопровождать в долгую?

Обычно PostgreSQL, если система основана на строгих правилах и связях. Схема, миграции через Flyway или Liquibase, явные внешние ключи — всё это делает поведение предсказуемым и позволяет легко отслеживать изменения. MongoDB проще там, где структура данных естественно документная и долго не усложняется, но требует дисциплины в версионировании документов, чтобы разные версии приложения не ломали друг друга несовместимыми полями.

Можно ли использовать обе базы сразу?

Да, и в некоторых проектах это лучший вариант. Главное — чётко разделить зоны ответственности между ними, не дублировать данные без необходимости и определить, какая база является источником истины для каждой сущности. В TSKLab мы не раз применяли гибрид: PostgreSQL для всего, что связано с деньгами и связями, MongoDB для событий и контента. Это работает, если архитектура сервисов позволяет каждому хранилищу жить независимо.