Введение в MongoDB

Illustration of a large wall of varied shelves filled with books, ornaments, a TV, potted plants, and scattered personal items, depicted in a stylized, monochromatic color scheme with orange accents.
Обновлено: | Опубликовано:
Illustration of a large wall of varied shelves filled with books, ornaments, a TV, potted plants, and scattered personal items, depicted in a stylized, monochromatic color scheme with orange accents.

В этой статье я хочу вам рассказать, почему вообще Mongo и стоит ли вам смотреть в ее сторону.

Для начала пару слов о моем опыте с ней. Попробовал я ее первый раз года четыре назад, когда она стала модная и все хотели ее попробовать, потому что NoSQL это то, что нужно любому стартапу!!! (на самом делел нет, читайте дальше) Но тогда дело далеко не зашло, побаловался, даже в каком-то из MVP ее применили, но в продакшн дело не пошло. С тех пор я ее, можно сказать, позабыл. Однако полтора года назад я устроился в компанию, где MongoDB активно используется. Там была развестистая микросервисная архитектура и один из микросервисов, весьма не микро, использовал как раз эту базу данных. Тут я вкусил ее по полной. Испытал и чувство наслаждения от того, как все легко меняется, и взрывы гнева от того, что неожиданности в ее поведении порой были слишком неожиданными. Теперь же я работаю в другом месте и Монга у нас используется с полной осознанностью с моей стороны и прикасаюсь я к ней ежедневно, можно даже сказать, ежечасно.

Итак, давайте разберем, почему вам стоит рассмотреть использование MongoDB в вашем проекте.

1. Отсутствие схемы.

Это самое очевидное преимущество. Если вы работаете над новым стартапов, в которым бизнес-модель еще не до конца ясна и с большой вероятностью проект до выхода на рынок претерпит множество изменений, в том числе на уровне организации данных - посмотрите в сторону NoSQL решений, в частности на Монгу. Все дело в том, что в отличие от моего горячо любимого PostgreSQL в Монге просто нет необходимости создавать таблицы, менять их схемы, создавать миграции, заботиться о типах данных. Однако тут будьте осторожны. Очевидный плюс этого пункта, что вам гораздо проще создавать новые таблицы, добавлять и убирать поля. Настолько просто, что в Mongoid (ORM для MongoDB) вы просто добавляете в вашу модель строчку а-ля field :text, type: String и все, при следующей записи в бд у нового элемента будет это поле. Если же вы вставляете данные без ORM - то вам и никакие "строчки" не нужны - просто пихайте, что душе угодно. Но тут же и темная сторона этой силы. Вы не можете быть вполне уверены, что в конкретном документе у вас есть конкретное поле. (примечание: документами в MongoDB называются записи в коллекции). Т.е. если раньше у вас не было поля text и вы добавили несколько записей, а потом добавили это поле и добавили еще записи - в старых записях у вас этого поля, конечно же, не появится. Спасибо Mongoid, он сделает вид, что такое поле есть и у них и просто вернет значение null.

2. Легкость горизонтального масштабирования.

Горизонтальное масштабирование требуется когда вам необходимо запихнуть в базу данных информации больше, чем диск на вашем сервере. Все, что связано с горизонтальным масштабированием является визитной карточкой любой NoSQL базы данных. Дальше они уже соревнуются в том, у кого выше надежность, у кого быстрее запись, у кого быстрее чтение и т.д. На момент написания этой статьи в PostgreSQL нет встроенного механизма горизонтального масштабирования. Есть сторонние проприетарные решения (не могу не упомянуть компанию Citus, они делают прекрасную работу). В MongoDB же это делается предельно просто, а статей про это написано много, и механизмы репликации вкупе с шардированием на ней работают прекрасно. Кроме того можно как позволить балансировщику автоматически выбирать, в какой шард складывать конкретные докуенты, так и задать правила относительно какого-то поля или набора болей.

3. Богатая функция аггрегации.

Язык SQL очень богатый и всем привычный, камней бросать я в него не стану. Однако то, как позволяет получать данные Монга однозначно заслуживает похвалы. Тут вам и map-reduce, и группировки по сложным условиям, и переформатирование документов на лету, и получение случайных документов, и сортировки. В общем все то, что вы можете выжать из SQL БД, плюс возможность записывать все это в формате pipeline'ов и с более читаемым синтаксисом.

Вот один из многих примеров из документации:

sql

SELECT cust_id,
       SUM(price) as total
FROM orders
WHERE status = 'A'
GROUP BY cust_id
HAVING total > 250

mongo

db.orders.aggregate( [
   { $match: { status: 'A' } },
   {
     $group: {
        _id: "$cust_id",
        total: { $sum: "$price" }
     }
   },
   { $match: { total: { $gt: 250 } } }
] )

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

4. Создана для денормализации.

В MongoDB принято хранить данные так, как вам это удобно. В SQL базах данных всегда (примечание: на самом деле нет, стоит всегда думать головой и не воспринимать слово "всегда" как закон) стоит заботиться об организации данных, чтобы таблицы были нормализованные, а запросы строить так, чтобы они могли левой пяткой глаз почесать, но данные достать. В Монго если вам неудобно, в каком формате или в каком месте лежат данные - вы с чистой совестью можете их или переместить, потому что отсутствие схемы это подразумевает, или просто продублирвать данные в нужное место. Т.е. фактически у вас может быть одно и то же поле с одними и теми же данными, но в разных коллекциях. Или два поля в одной коллекции, а плюс к ним еще одно поле, которое является композицией первых двух. Но это опять таки та сила, которую следует применять с умом. Если вы будете неконтролируемо плодить поля в документах, поддержка на уровне понимания разработчиком сущности будет становиться все труднее и труднее.

5. Простой формат индексов.

Индексы в MongoDB называются предельно понятно и их использование практически лишено подводных камней. Например в Постгресе если у вас есть b-tree индекс на одно поле и gist индекс на другое - при запросе, который использует оба этих индекса, использоваться будет только один из них. В Монге таких сюрпризов меньше.

Заключение

Несомненно MongoDB не серебряная пуля. В ней есть свои неожиданные подводные камни. Например она автоматически не отрубает медленные запросы и они продолжают висеть, пока вы их не закроете саомостоятельно. Еще вы можете испытать низкую производительность при count запросе на больших коллекциях. Но это все вещи, которые ты однажды узнаешь и потом просто помнишь о них, потому что жить они не сильно мешают. Я не агитирую всех уходить с SQL БД и переводить продакшн проекты на Монгу, но если вы стоите перед выбором, какую базу данных взять для нового проекта - подумайте о ней. Если все-таки не решитесь экспериментировать с NoSQL решением - тогда берите PostgreSQL. Они очень динамично развиваются, у них есть частично-nosql решение в виде json полей в таблице, огромное количество документации и прекрасная производительность. В общем не пожалеете. Но это тема для другой статьи.

Subscribe to our Newsletter

Let us send you the best of what we've discovered in DevOps, Cloud and Kubernetes, as well us occasional event announcements.

We are also preparing some ways to learn together: weekly challenges, free courses and more. Subscribe now to be the first to get those.