Дети часто задаются вопросом - кто сильнее, кит или слон? каратист или боксер? В этой статье мы попробуем ответить на на похожий вопрос, сравнив SQL (ну или почти SQL) базу данных PostgreSQL и NoSQL базу данных MongoDB. И понять, для каких проектов лучше подойдет реляционная PostgreSQL, а для каких MongoDB.

Данное сравнение также важно, потому что, учитывая новый функционал, MongoDB стала обладать некоторыми качествами SQL СУБД, включая многодокументные ACID-транзакции, вторичный индекс и расширенные возможности запросов. А PostgreSQL расширяет возможности работы с JSON, включаяиндексирование и оптимизацию запросов.

Принципиальные отличия архитектуры

Начнем с того, чем концептуально отличается PostgreSQL от MongoDB.

PostgreSQL - это реляционная база данных, где данные представлены таблицами со связями по ключам. Графически это можно представить следующим образом.

Пример таблиц и связей в реляционной базе данных
Пример таблиц и связей в реляционной базе данных

MongoDB - это документо-ориентированная NoSQL база данных. MongoDB работает с коллекциями документов и самими документами. Схематически это можно представить следующим образом:

Хранение данных в документо-ориентированной СУБД
Хранение данных в документо-ориентированной СУБД

Данные архитектурные отличия являются первопричиной функциональных и качественных различий PostgreSQL и MongoDB.

Качественное различие №1 - масштабируемость

PostgreSQL хорошо масштабируется вертикально, но в концепции “ванильной” версии создание кластеров не предусмотрено. Хотя есть реализации с созданием кластеров PostgreSQL, это нетривиальная задача, сопряженная с рядом сложностей и требующая специализированных навыков. Кроме того, кластеры реляционных баз масштабируются только до определенного предела. Вдобавок, одна таблица в PostgreSQL не может занимать более 32 Тб, а одна запись - не более 1,6 Тб.

Что касается MongoDB, то возможность легкого горизонтального масштабирования уже заложена в ее архитектуру, хотя и имеет определенные ограничения для начального сегментирования (32 Тб на одну коллекцию).

Качественное различие №2 - ACID-транзакции

Небольшое напоминание про ACID.

ACID транзакции - это такие транзакции, которые гарантируют атомарность, согласованность, изоляцию и устойчивость. Атомарность гарантирует, что никакая транзакция не будет зафиксирована в системе частично. Будут либо выполнены все её подоперации, либо не выполнено ни одной. Согласованность гарантирует, что каждая успешная транзакция по определению фиксирует только допустимые результаты. Изолированность гарантирует, что во время выполнения транзакции параллельные транзакции не окажут влияния на её результат. А устойчивость гарантирует сохранность внесенных изменений вне зависимости от внешних факторов.

PostgreSQL изначально разрабатывался так, чтобы поддерживать высокий уровень соответствия принципам AСID. 

В MongoDB официальная поддержка AСID появилась с версии v4 в 2018 году. 

Атомарные модификаторы в MongoDB могут работать только с одним документом, что не дает гарантии при транзакциях с несколькими коллекциями (таблицами). 

Также по умолчанию MongoDB не сохраняет ваши изменения на диск сразу. Таким образом, есть вероятность следующей ситуации: статус обновления - “выполнено успешно”, но при условном отключении питания данное обновление будет потеряно.MongoDB предоставляет параметры для управления уровнем «долговечности» обновлений. СУБД может дождаться, пока другие реплики получат это обновление (в памяти), дождаться записи в локальный файл журнала и т. д. 

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

Таким образом MongoDB имеет:

  • атомарность на уровне документа (хотя с версии v4 атомарность расширена и на коллекции, но с рядом ограничений), что не вполне соответствует полной атомарности,

  • окончательную, а не моментальную согласованность, что гарантирует согласованность только через определенное время, не гарантирует полную изоляцию и обеспечивает меньшую устойчивость в сравнении с PostgreSQL.

В большинстве случаев вы не заметите принципиальной разницы, но если требования AСID для вас критичны (вы банк и сумма должна сходиться “копейка в копейку” вне зависимости от внешних факторов и режимов эксплуатации), предпочтительнее будет использовать СУБД изначально адаптированную под транзакционные нагрузки, такую как PostgreSQL.

Качественное различие №3 - организация хранения данных

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

Функциональные отличия MongoDB от PostgreSQL

№1 Работа с JSON

Как MongoDB, так и PostgreSQL умеют обрабатывать JSON. MongoDB хранит JSON, используя собственный формат BSON , а Postgres формат JSONB. 

MongoDB обладает двумя преимуществами:

  1. Встроенным валидатором схемы.

  2. Интеграцией с экосистемой Node.js, что упрощает использование при разработке на Node.

№2 Производительность

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

Postgres лучше справляется со сложными запросами благодаря SQL и встроенному оптимизатору запросов.

Лицензии и тренды развития

PostgreSQL распространяется под открытой либеральной лицензией, аналогичной MIT и BSD лицензии. Помимо этого PostgreSQL имеет очень активное сообщество и развитую экосистему, что позволяет продукту активно развиваться и расширять долю рынка.

MongoDB распространяется по лицензии, которую нельзя назвать Open Source (она скорее проприетарная и близка к AGPL v3). Данная лицензия накладывает мало ограничений для персонального использования, но не позволяет использовать MongoDB как лицензируемую часть коммерческих решений, создавать конкурентные решения и предоставлять managed сервисы.

Сравнение PostgreSQL vs MongoDB

PostgreSQL

MongoDB

Вывод

Вид базы данных

Реляционная

Документо-ориентированная

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

Лицензия

Аналогичная MIT и BSD лицензии

Проприетарная, близкая к AGPL v3

PostgreSQL распространяется по более либеральной лицензии

Масштабируемость

Хорошая вертикальная масштабируемость, ограниченная горизонтальная

Высокая горизонтальная масштабируемость

Обе базы обладают возможностями масштабирования, но горизонтальная масштабируемость MongoDB лучше

ACID - транзакции

Поддерживаются

Поддерживаются, но с рядом существенных ограничений

Обе СУБД поддерживают AСID-транзакции, но MongoDB обладает рядом ограничений, не позволяющих однозначно соответствовать ASID.

Организация хранения данных

В таблицах, со связями по ключам

В виде документов с разбивкой по коллекциям

PostgreSQL лучше подходит для транзакционных нагрузок, а MongoDB для хранения большого объема документов

Работа с JSON

Поддерживается в формате JSONB

Поддерживается в формате BSON

Поддерживается обеими базами данных, но поддержка MongoDB включает более широкий функционал

Производительность

Лучше справляется со сложными запросами благодаря SQL и встроенному оптимизатору запросов

Работает быстрее если в операции задействованы различные объекты

Для разных типов использования производительность различается. Если у вас присутствуют сложные запросы, целесообразно выбрать PostgreSQL

Порог входа и гибкость использования

Имеет средний порог входа, невысокую гибкость (возможность быстрых изменений) и среднюю по сложности кривую обучения

Имеет низкий порог входа, простую кривую обучения и высокую гибкость при использовании

MongoDB обладает более низким порогом входа, криво обучения и более высокой адаптивностью при использовании

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


Вы можете развернуть базы данных PostgreSQL и MongoDB в облаке Amvera Cloud c помощью push в выделенный Git-репозиторий. Для хостинга баз данных PostgreSQL и MongoDB нужно выполнить несколько простых шагов, описанных в инструкциях для PostgreSQL и MongoDB соответственно. Стоимость хостинга СУБД начинается от 170 руб. в месяц с поминутной тарификацией. Для теста системы вы можете использовать код QCOWI100, который добавит немного баланса для проведения экспериментов без необходимости предварительной оплаты.

Комментарии (16)


  1. Data4
    29.08.2023 05:33
    +9

    Конечно, сравнение MongoDB и PostgreSQL, это как удава в попугаях измерять. Сильно уж разные СУБД для разных задач. Но как совсем база для начала изучения - может быть.


  1. ggo
    29.08.2023 05:33
    +3

    Это связано с тем, что данные денормализованы и не требуют дорогостоящих соединений между таблицами. 

    Денормализация денормализации рознь.
    Есть кейсы, когда нормализация наоборот ускоряет манипуляции с данными.

    Для монги главный фактор для использования: требуется дешевое горизонтальное масштабирование. Во всех остальных случаях: стоит подумать нужна ли реально монга, потому что потом будет больно с нее съезжать, т.к. честный ACID снимает кучу головняков, не только для "денежных" сервисов.


  1. onyxmaster
    29.08.2023 05:33
    +2

    Одно из самых важных отличий -- простота обеспечения отказоустойчивости и шардирования. В MongoDB поддержка нескольких узлов есть "из коробки", а PostgreSQL же в этом плане -- конструктор "собери сам", вот вам встроенная поддержка репликации на основе WAL, а дальше сами.
    Пулинг соединений, балансировка, failover, шардирование, логическая или физическая репликация -- всё выбери сам, настрой сам и борись с багами в сторонних утилитах тоже сам =)


    1. onyxmaster
      29.08.2023 05:33

      Минус есть, ответа нет. С чем не согласен минусующий? С важностью отличия или с тем что у PostgreSQL нет в стандартной поставке готового механизма шардинга и обеспечения отказоустойчивости?

      У нас, если что, в эксплуатации и MongoDB есть и PostgreSQL, причём больше 10 лет и то и другое.


  1. nin-jin
    29.08.2023 05:33
    +2

    В MongoDB официальная поддержка AСID появилась с версии v4 в 2018 году. 

    То ест до 4 версии, MongoDB не могла называться СУБД.

    Атомарные модификаторы в MongoDB могут работать только с одним документом

    А с 4 версии, она стала СУБД только на пол шишечки.


    1. onyxmaster
      29.08.2023 05:33

      Я знаю что хейтить MongoDB модно (особенно тем, кто про неё читал в интернете "она теряет данные"), но её вполне можно было использовать примерно с версии 1.8.


      1. nin-jin
        29.08.2023 05:33
        -2

        А вы точно знаете, чем субд отличается от просто файлика на диске?


        1. onyxmaster
          29.08.2023 05:33

          А вы как собираетесь оценивать точность моего знания? По тому, совпадает ли оно с вашим или нет? Беспроигрышный вариант! То что у вас невысокое мнение о MongoDB, по той или иной причине, не говорит ничего о её качестве и "настоящести". В нашем проекте (170млн запросов от клиентов в сутки) работает нормально, в разных ролях, и как основное хранилище, и как объектное хранилище, и как in-memory кэш и сервис очередей. Могла бы быть побыстрее в некоторых сценариях, ну тут уж куда деваться, что есть то есть.

          А если ответить на ваш вопрос нейтрально, то всё зависит от требований. Даже "файлик на диске" может быть частью СУБД, на SQLite можете посмотреть например или на BerkeleyDB.


          1. nin-jin
            29.08.2023 05:33
            +1

            Я вам по секрету скажу: все СУБД хранят БД в виде файликов на диске.


            1. onyxmaster
              29.08.2023 05:33
              +2

              Благодарю за предоставленную вами информацию =)


  1. ptr128
    29.08.2023 05:33
    +1

    Про 32ТБ лимит у PostgreSQL - слишком толсто. Это все же ограничение на одну partition, коих можно иметь десятки тысяч для одной таблицы.

    Главное достоинство MongoDB, одновременно и главный ее недостаток - горизонтальное масштабирование из коробки, ценой отсутствия транзакционной целостности между документами.


    1. mosinnik
      29.08.2023 05:33

      Да и для монги тоже 32Тб не предел. А про транзакции уже давно есть мультидокументные, которые в пределах узла реплики атомарны. А если надо то и на кластере можно, но ценой резкого увеличения времени выполнения запроса.


      1. ptr128
        29.08.2023 05:33

        В статье же сказано

        одна таблица в PostgreSQL не может занимать более 32 Тб

        А это ложное утверждение, так как 32 ТБ - ограничение на один раздел, а не таблицу.

        транзакции уже давно есть мультидокументные

        Уже нет. Появились в 4.0, а в 4.2 их заменили распределенными транзакциями.

        Но самое главное, что это не совсем транзакции. С одной стороны, да, они гарантируют, что если в транзакции были изменены несколько документов, то до фиксации транзакции эти изменения не видит никто (запрещено грязное чтение). Но с другой стороны, фиксация устроена таким образом, что после нее клиент вполне может видеть только часть из документов, участвовавших в транзакции. Этот момент явно описан в документации:

        if a transaction is committed and write 1 is visible on shard A but write 2 is not yet visible on shard B, an outside read at read concern"local"can read the results of write 1 without seeing write 2

        Лично у меня называть это транзакционной целостностью язык не поворачивается.


        1. onyxmaster
          29.08.2023 05:33

          Ну read concern local это всё-таки не про транзакции, так же как и write concern, отличный от majority. Есть read concern majority, есть, если уж очень надо -- linearizable.


          1. ptr128
            29.08.2023 05:33

            После чего все выгоды от шардирования теряются. Вернулись к тому, с чего начали. "Вам горизонтальное масштабирование или транзакционной целостность?"


            1. onyxmaster
              29.08.2023 05:33

              Товарищ Брюер что-то знал, когда постулировал CAP-гипотезу (теоремой всё-таки называть не стану). Но если почитать про Spanner того же Брюера, то не всё так однозначно =)