Выбор базы данных не должен быть легким решением

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

  • Что такое лицензирование?
  • Что означает, что MongoDB - это база данных NoSQL?
  • Что насчет производительности MongoDB?

Лицензирование

MongoDB была лицензирована в соответствии с GNU AGPL v3.0 Free Software Foundation до 16 октября 2018 г. Теперь она находится под лицензией MongoDB Server Side Public License. На практике оба варианта означают, что улучшения, которые вы вносите в MongoDB для опубликованной работы, должны быть переданы сообществу. Исходный код любой производной работы также должен распространяться.

Вы можете задаться вопросом, является ли ваше приложение производным произведением. Должен признаться, я так и не нашел простого определения этому термину. Однако в конкретном случае MongoDB они просто распознают приложения, использующие их базу данных, это отдельная работа.

Более того, их поддерживаемые драйверы выпускаются под Apache License v2.0. Это разрешительная лицензия. Вам не нужно публиковать исходный код, и ваше приложение обычно общается с MongoDB только с помощью драйвера.

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

Примечание. Хотя большой опыт заставляет меня доверять этому анализу, я не юрист. Представленное здесь мнение является моим личным пониманием и не является официальным.

NoSQL

Да, MongoDB - это база данных NoSQL. Это слово может сбивать с толку. Я попытаюсь проанализировать наиболее распространенные идеи, сосредоточив внимание на том, как это применимо к MongoDB.

Документально-ориентированный

В традиционных базах данных SQL данные организованы в виде таблиц и строк. Каждая строка имеет фиксированное количество столбцов, в которых могут храниться данные только определенного типа (например, целые числа, текст, дата и время). Это определяет схему ваших данных.

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

Транзакционный

До версии 4 MongoDB предоставляла только транзакции на уровне документа. Записи никогда не применялись частично к вставленному или обновленному документу. Операция была атомарной в том смысле, что она либо не удалась, либо завершилась успешно. Что касается документа в целом, на уровне документа он был назван ACID.

Как следствие, не было возможности атомарных изменений, охватывающих несколько документов. Вам нужно было эмулировать необходимые транзакции базы данных (например, с помощью двухфазной фиксации).

Начиная с версии 4, MongoDB поддерживает транзакции ACID с несколькими документами, что делает его единственной базой данных с открытым исходным кодом, в которой модель документа сочетается с гарантиями ACID.

Schemaless (правда?)

Это означает, что вам не нужно сообщать базе данных структуру ваших данных и примитивные типы, которые будут использоваться, прежде чем вы сможете управлять ими.

Это также означает, что вы можете смешивать документы с разными структурами в одном и том же наборе данных.

Одним из больших преимуществ является упрощение миграции схемы (большинство корректировок в базе данных прозрачны и автоматически). Откат вряд ли вызовет проблемы. Еще одно преимущество заключается в простом динамическом расширении существующих моделей данных с помощью настраиваемых атрибутов во время выполнения.

Но все это не означает, что у вас вообще нет схемы. Если он не объявлен явно, он неявно отражается в логике вашего приложения. Он может быть объявлен другими способами для обработки проверки формы / данных. В любом случае вам все равно нужно явно указать базе данных, как создавать индексы для обеспечения хорошей производительности.

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

Нереляционный (правда?)

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

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

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

  • По ID, затем вы можете заполнить его вручную вторым запросом или с помощью DBRefs
  • По любому другому полю можно использовать $lookupоператор

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

Представление

Читай пиши

Да, MongoDB, как и любая другая настоящая база данных, предназначена для обработки огромного объема данных. Короче говоря, обработка сотен или тысяч объектов - это ничто для базы данных, поэтому вам не нужно беспокоиться, если у вас есть такие числа.

Вы можете найти множество тестов. Вот простой пример, чтобы дать вам приблизительную оценку. Сохраненные документы действительно просты и обычно представляют собой измерения с отметкой времени:

{
    value: random(0,100),
    timestamp: date
}

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

Оба атрибута проиндексированы. MongoDB автоматически добавляет и индексирует уникальный идентификатор документа. Я проверил три запроса:

  • Найдите максимальное значение коллекции, используя фреймворк агрегации
  • Найдите 100 наибольших значений больше 99,9
  • Получите единый документ по ID

Максимальный запрос не использует индексы из-за агрегации, в то время как запросы больше чем и по идентификатору могут его использовать. Вы увидите, насколько это важно для производительности.

В качестве тестовой конфигурации использовалась 64-разрядная конфигурация MongoDB 3.4.1 - ОС Windows 7 Pro SP1 - ЦП Core i7–4712HQ 2,3 ГГц - ОЗУ 16 ГБ - SSD HD. Результаты тестирования были следующими:

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

Вот сценарии, используемые для создания / запроса базы данных для этого теста:

И команды запуска:

// Launch server
./mongod --dbpath "C:\Program Files\MongoDB\Server\3.4\data" --port 27018
// Insertion exemple for 10e7
./mongo --port 27018 --eval "var arg1=10000000" create_collection.js
// Requests
./mongo --port 27018 --eval "" query_collection.js

объем памяти

Да, MongoDB часто выглядит так, будто использует всю доступную оперативную память. На самом деле он полагается на разные механизмы хранения. WiredTiger - это значение по умолчанию, начиная с MongoDB 3.2, а MMAPv1 - это значение по умолчанию для версий MongoDB до 3.2. Однако они работают примерно одинаково. Через кеш файловой системы они автоматически используют всю свободную память, которая не используется кешем движка или другими процессами. И это логично, если вы хотите добиться максимальной производительности.

Таким образом, мониторы системных ресурсов часто показывают, что MongoDB использует много памяти, но ее использование является динамическим. Если другому процессу внезапно понадобится половина ОЗУ сервера, MongoDB предоставит кэшированную память другому процессу.

Как следствие, единственный параметр, который вы можете настроить для оптимизации использования памяти, - это размер кэша движка. Например, по умолчанию механизм WiredTiger использует 50% ОЗУ минус 1 ГБ, что может быть довольно большим на серверах с большим объемом памяти. Это может даже вызвать некоторые проблемы, если вы используете контейнеры с ограниченной памятью, так что просто найдите правильный баланс для вашего варианта использования.

Заключение

Я надеюсь, что теперь у вас есть более точное представление о преимуществах, предоставляемых MongoDB, если это соответствует вашим потребностям.

Недавно MongoDB запустила предложение база данных как услуга под названием MongoDB Atlas, которое вам может быть полезно протестировать.