В этой статье я хочу вам рассказать, почему вообще Mongo и стоит ли вам смотреть в ее сторону.
Для начала пару слов о моем опыте с ней. Попробовал я ее первый раз года четыре назад, когда она стала модная и все хотели ее попробовать, потому что NoSQL это то, что нужно любому стартапу. (на самом делел нет, читайте дальше) Но тогда дело далеко не зашло, побаловался, даже в каком-то из MVP ее применили, но в продакшн дело не пошло. С тех пор я ее, можно сказать, позабыл.
Однако полтора года назад я устроился в компанию, где MongoDB активно используется. Там была развестистая микросервисная архитектура и один из микросервисов, весьма не микро, использовал как раз эту базу данных. Тут я вкусил ее по полной. Испытал и чувство наслаждения от того, как все легко меняется, и взрывы гнева от того, что неожиданности в ее поведении порой были слишком неожиданными. Теперь же я работаю в другом месте и Монга у нас используется с полной осознанностью с моей стороны и прикасаюсь я к ней ежедневно, можно даже сказать, ежечасно.
Как работают NoSQL базы: документ-ориентированные типа MongoDB
Итак, давайте разберем, почему вам стоит рассмотреть использование MongoDB в вашем проекте.
1. Отсутствие схемы.
Это самое очевидное преимущество. Если вы работаете над новым стартапов, в которым бизнес-модель еще не до конца ясна и с большой вероятностью проект до выхода на рынок претерпит множество изменений, в том числе на уровне организации данных — посмотрите в сторону NoSQL решений, в частности на Монгу.
Все дело в том, что в отличие от моего горячо любимого PostgreSQL в Монге просто нет необходимости создавать таблицы, менять их схемы, создавать миграции, заботиться о типах данных. Однако тут будьте осторожны. Очевидный плюс этого пункта, что вам гораздо проще создавать новые таблицы, добавлять и убирать поля.
Настолько просто, что в Mongoid (ORM для MongoDB) вы просто добавляете в вашу модель строчку а-ля field :text, type: String и все, при следующей записи в бд у нового элемента будет это поле. Если же вы вставляете данные без ORM — то вам и никакие «строчки» не нужны — просто пихайте, что душе угодно. Но тут же и темная сторона этой силы.
Вы не можете быть вполне уверены, что в конкретном документе у вас есть конкретное поле. (примечание: документами в MongoDB называются записи в коллекции). Т.е. если раньше у вас не было поля text и вы добавили несколько записей, а потом добавили это поле и добавили еще записи — в старых записях у вас этого поля, конечно же, не появится. Спасибо Mongoid, он сделает вид, что такое поле есть и у них и просто вернет значение null.
2. Легкость горизонтального масштабирования.
Горизонтальное масштабирование требуется когда вам необходимо запихнуть в базу данных информации больше, чем диск на вашем сервере. Все, что связано с горизонтальным масштабированием является визитной карточкой любой NoSQL базы данных. Дальше они уже соревнуются в том, у кого выше надежность, у кого быстрее запись, у кого быстрее чтение и т.д.
MongoDB #1 Основные понятия (Basic Concepts)
На момент написания этой статьи в 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 полей в таблице, огромное количество документации и прекрасная производительность. В общем не пожалеете. Но это тема для другой статьи.
Источник: mkdev.me
За и против: Когда стоит и не стоит использовать MongoDB
Разработчик и сотрудник проекта CouldBoost.io Наваз Дандала (Nawaz Dhandala) написал материал о том, почему в некоторых случаях не стоит использовать MongoDB. Мы в «Латере» развиваем биллинг для операторов связи «Гидра» и уже много лет работаем с этой СУБД, поэтому решили представить и свое мнение по данному вопросу.
Дандала сразу оговаривается, что работал со многими СУБД (как SQL, так и NoSQL) и считает MongoDB отличным инструментом, однако существуют сценарии, в которых его применение нецелесообразно.
Документоориентированные СУБД такие, как MongoDB, прекрасно справляются с хранением JSON-данных, сгруппированных в «коллекции». В таком формате можно хранить любые JSON-документы и удобно категоризировать и по коллекциям. Содержащийся в MongoDB JSON-документ называется двоичным JSON или BSON и, как любой другой документ этого формата, является неструктурированным. Поэтому, в отличии от традиционных СУБД, в коллекциях можно сохранять любые виды данных, и эта гибкость сочетается с горизонтальной масштабируемостью базы данных. Эта возможность нравится многим разработчикам, однако «не все так однозначно».
Если MongoDB такая классная, почему ее не используют все и всегда?
Выбор СУБД зависит в том числе и от того, что за приложение планируется создать. То есть базу данных выбирают не разработчики, а сам продукт, убежден Дандала. Он приводит пример, подтверждающий этот тезис.
При создании приложения, концепция которого подразумевает работу с документами, MongoDB будет хорошим выбором. К такому типу приложений можно отнести, к примеру, движок блог-платформы, где каждый автор сможет иметь по несколько блогов, и каждый из них будет содержать множество комментариев. База данных для обслуживания такого приложения должна быть легко расширяемой, и здесь MongoDB подойдет как нельзя лучше.
Однако, необходимо отметить, что у MongoDB нет связей между документами и “коллекциями” (частично это компенсируется Database Reference — ссылками в СУБД, но это не полностью решает проблему). В итоге, возникает ситуация, при которой имеется некий набор данных, который никак не связан с другой информацией в базе, и не существует никакого способа объединить данные из различных документов. В SQL-системах это было бы элементарной задачей.
Здесь возникает другой вопрос — если в MongoDB нет связей и возможностей по объединению двух таблиц, то зачем ее тогда вообще использовать? Ответ — потому что эта СУБД отлично масштабируется, и по сравнению с традиционными SQL-системами, гораздо быстрее осуществляет чтение и запись.MongoDB прекрасно подходит для приложений, в которых практически не используются данные с зависимостями и необходима масштабируемость базы данных.
Многие разработчики применяют MongoDB и для хранения связанных данных, реализуя объединения вручную в коде — этого достаточно в сценариях «одноуровневого» объединения или малого количества связей. То есть данный метод далеко не универсален.
Так какую СУБД выбрать?
Существует огромное количество различных СУБД, и каждая из них соответствует определённому набору требований, которые разработчики предъявляют к своему приложению:
- Документоориентированные СУБД (к примеру, MongoDB): Как уже сказано выше, документоориентированные СУБД используются для хранения JSON-документов в “коллекциях” и осуществления запросов по нужным полям. Можно использовать эту базу данных для создания приложений, в которых не будет содержаться слишком большого количества связей. Хорошим примером такого приложения является движок для блог-платформы или хранения каталога продуктов.
- Графовые СУБД (например Neo4j): Графовая СУБД используется для хранения между субъектами, где узлы являются субъектами, а грани — связями. Например, если разработчики создают социальную сеть, и один пользователь подписывается на другого, то пользователи являются узлами, а их “подписка” — связью. Такие СУБД прекрасно справляются с образованием связей, даже если глубина таких связей более ста уровней. Этот инструмент столь эффективен, что может даже позволяет выявлять мошенничество в сфере электронной коммерции.
- Кэш (например Redis): Такие СУБД используются, когда требуется крайне быстрый доступ к данным. Если создается приложение для интернет-торговли, в котором есть подгружаемые на каждой страницы категории, то вместо обращения к базе данных при каждом чтении, что крайне затратно, можно хранить данные в кэше. Он позволяет быстро осуществлять операции чтения/записи. Дандала советует применять СУБД, использующие кэш, в качестве оболочки для обработки часто запрашиваемых данных, избавляющей от необходимости совершения частых запросов к самой базе.
- Поисковые СУБД (например ElasticSearch): В случае необходимости осуществления полнотекстового поиска по базе данных (например поиск продукции в ecommerce-приложении), то хорошей идее будет использование поисковой СУБД вроде ElasticSearch. Эта система способна искать по огромному массиву данных и обладает обширной функциональностью — например, СУБД умеет осуществлять поиск по именованным категориям.
- Строковые СУБД (например Cassandra): СУБД Cassandra используется для хранения последовательных данных, логов, или огромного объема информации, который может генерироваться автоматически — к примеру, каким-нибудь датчиками. Если разработчики собираются использовать СУБД для записи больших массивов данных и при этом планируется, что будет намного меньше обращений для чтения и данные не будут иметь связи и объединения, тогда Cassandra будет хорошим выбором, уверен Дандала.
Использование комбинации баз данных
Существуют и ситуации, в которых может понадобиться использование сразу нескольких различных СУБД.
Например, если в приложении есть функция поиска, то его можно реализовать с помощью ElasticSearch, а уже для хранения данных без связей лучше подойдет MongoDB. Если речь иет о проекте в сфере «интернета вещей», где огромное количество всевозможных устройств и датчиков генерируют гигантские объёмы данных, вполне разумно будет использовать Cassandra.
Принцип, при котором используются несколько СУБД для работы в одном приложении, называется “Polyglot Persistence”. В этой статье можно почитать о плюсах и минусах такого подхода.
Наш опыт
Наша биллинговая система «Гидра» использует для учета первичных данных и хранения финансовой информации реляционную СУБД. Она идеально подходит для этих целей. Но некоторые модули Гидры, например, RADIUS-сервер, работают под высокой нагрузкой и могут получать тысячи запросов в секунду с жесткими ограничениями на время обработки запроса. Кроме того, в БД нашего автономного RADIUS-сервера данные хранятся в виде набора AVP (attribute/value pair). В таком сценарии реляционная СУБД уже не выглядит лучшим решением, и тут на помощь приходит MongoDB с ее хранилищем документов произвольной структуры, быстрой выдачей ответа и горизонтальной масштабируемостью.
При эксплуатации более чем на 100 инсталляциях Гидры на протяжении последних 5 лет серьезных проблем с Mongo мы не обнаружили. Но пара нюансов все же есть. Во-первых, после внезапного отключения сервера БД хоть и восстанавливается благодаря журналу, но происходит это медленно. К счастью, необходимость в этом возникает нечасто.
Во-вторых, даже при небольшом размере БД редко используемые данные сбрасываются на диск и когда запрос к ним все же приходит, их извлечение занимает много времени. В результате нарушаются ограничения на время выполнения запроса.
Все это относится к движку MMAPv1, который применяется в Mongo по умолчанию. С другими (WiredTiger и InMemory) мы пока не экспериментировали — проблемы не настолько серьезны.
Источник: habr.com
Не только SQL: знакомимся с документо-ориентированной базой данных MongoDB
Хотя большинство системных и бизнес-аналитиков чаще сталкиваются с реляционными базами данных, будет полезным знать про другие альтернативы. Сегодня рассмотрим примеры работы с документо-ориентированной NoSQL-базой MongoDB, развернутой в онлайн-песочнице https://mongoplayground.net/.
Что такое MongoDB и как она работает: краткий ликбез
Здесь я уже упоминала про различные виды NoSQL-баз. Они предназначены для хранения больших объемов данных со сложной или изменяющейся структурой. В отличие от реляционных баз данных, NoSQL-СУБД обычно не поддерживают стандартный язык SQL-запросов, а данные в них хранятся не в связанных таблицах, а в других структурах, оптимизированных под варианты использования.
Например, графовая база данных Neo4j, о которой я рассказываю в этой статье, хранит данные в виде графа и отлично решает задачи анализа социальных связей, поиска оптимальных путей, исследования трафика и других подобных задач. А документо-ориентированная база данных MongoDB хорошо справляется с задачами управления разнообразным контентом. К примеру, системы чат-ботов для поддержки пользователей на сайтах, где можно отправить вопрос оператору, при желании указать свои имя и контакты (емейл и/или телефон) для последующей связи, а также присоединить к обращению скриншот или другое вложение.
В качестве примера рассмотрим случай, с которым мы часто сталкиваемся в нашем учебном центре, когда клиент оставляет заявку на обучение. Несмотря на ограниченный список полей в форме обратной связи (Курс, Имя, Емейл, Телефон, Сообщение), заявки заполняются с разной степенью полноты. Кто-то не хочет оставлять свой номер телефона и не заполняет это поле, а кому-то нужно дать больше вводной информации о своих потребностях, что вносится в поле Сообщение. Рассмотрим, как представить сведения по заявкам физических лиц и корпоративных клиентов в документо-ориентированной базе данных MongoDB.
Для этого сперва вспомним основные принципы работы этого NoSQL-хранилища:
- вместо таблиц MongoDB использует коллекции, где хранятся документы – аналоги строк в реляционной БД;
- MongoDB хранит данные в виде JSON-документов с различным уровнем глубины, кодируя их в бинарном формате BSON, который добавляет поддержку таких типов данных, как Date и binary, изначально не поддерживаемых в JSON;
- разные коллекции могут иметь разные структуры, причем даже в рамках одной коллекции у документов может различаться набор полей и их типы данных;
- будучи NoSQL-хранилищем, MongoDB не поддерживает классические SQL-запросы и по-своему реализует некоторые операции. В частности, вместо соединения таблиц с оператором JOIN в MongoDB применяется сохранение нескольких документов в одну коллекцию, чтобы потом работать с ней. Поддерживаются операции вставки, изменения и удаления данных, а также выборки документов с фильтрацией, группировкой и агрегацией по значениям полей.
Поняв ключевые особенности хранения данных в MongoDB, рассмотрим, как сохранить в этой NoSQL-СУБД данные по заявкам клиентов. Также рассмотрим, как сделать запросы к ним.
Источник: babok-school.ru