Перевод статьи подготовлен в преддверии старта курса
Основные моменты:
- Крайне важно разработать схему несмотря на то, что в MongoDB она необязательна.
- Аналогично, индексы должны соответствовать вашей схеме и шаблонами доступа.
- Избегайте использования больших объектов и больших массивов.
- Будьте осторожны с настройками MongoDB, особенно если речь идет о безопасности и надежности.
- В MongoDB нет оптимизатора запросов, поэтому вы должны быть осторожны при выполнении операций запроса.
Я очень давно работаю с базами данных, но только недавно открыл для себя MongoDB. Есть несколько вещей, которые я хотел бы знать перед началом работы с ней. Когда у человека уже есть опыт в определенной сфере, у него существуют предвзятые представления о том, что такое базы данных и что они делают. В надежде облегчить задачу понимания другим людям, представляю список распространенных ошибок.
Создание сервера MongoDB без аутентификации
К сожалению, MongoDB по умолчанию ставится без аутентификации. Для рабочей станции, доступ к которой устанавливается локально, такая практика нормальна. Но поскольку MongoDB – это многопользовательская система, которая любит использовать большие объемы памяти, будет лучше, если вы поставите ее на сервер с максимально возможным в ваших условиях количеством оперативной памяти, даже если собираетесь использовать ее только для разработки. Установка на сервер через порт по умолчанию может оказаться проблемной, особенно, если в запросе можно выполнить любой код на javascript (например, $where
в качестве идеи для
Есть несколько методов аутентификации, но проще всего установить для пользователя ID/пароль. Воспользуйтесь этой идеей, пока будете думать над причудливой аутентификацией на основе
Не забудьте привязать поверхность атаки к MongoDB
,
или
. Поскольку в стандартной MongoDB файлы данных не зашифрованы, разумно запускать MongoDB с
Ошибка при разработке схемы
MongoDB не использует схему. Но это не значит, что схема не нужна. Если вы хотите просто хранить документы без какой-либо согласованной схемы, сохранять их можно быстро и просто, но извлечь их потом может быть
Классическая статья «
Не забудьте о порядке сортировки
Забыв о порядке сортировки можно сильнее всего разочароваться и потерять больше времени, чем при использовании любой другой неправильной конфигурации. По умолчанию MongoBD использует
Создание коллекций с большими документами
MongoDB рада разместить большие документы размером до 16 МБ в коллекциях, а
Создание документов с большими массивами
Документы могут содержать массивы. Лучше всего, если количество элементов в массиве далеко от четырехзначного числа. Если элементы к массиву добавляются часто, он перерастет содержащий его документ, и его нужно будет
В MongoDB есть так называемый
Вы можете подумать, что обойтись можно без индексации массивов. К сожалению, из-за отсутствия индексов у вас могут появиться другие проблемы. Поскольку документы просматриваются от начала до конца, поиск элементов в конце массива будет занимать больше времени, да и большинство операций, связанных с таким документом, будут
Не забудьте, что порядок стадий в агрегации имеет значение
В системе базы данных с оптимизатором запросов, запросы, которые вы пишете, являются объяснениями того, что вы хотите получить, а не того, как это получить. Работает такой механизм по аналогии с заказом в ресторане: обычно вы просто заказываете блюдо, а не даете подробные инструкции повару.
В MongoDB вы инструктируете повара. Например, нужно убедиться, что данные проходят через reduce
как можно раньше в пайплайне с помощью $match
и $project
, а сортировка происходит только после reduce
, и что поиск происходит ровно в том порядке, в котором вам нужно. Наличие оптимизатора запросов, который избавляет от лишней работы, оптимально упорядочивает этапы и выбирает тип соединения, может вас избаловать. В MongoDB у вас появляется больше контроля ценой удобства.
Такие инструменты как
Использование быстрой записи
Никогда не устанавливайте в MongoDB параметры записи с высокой скоростью, но низкой надежностью. Этот режим «file-and-forget» кажется быстрым, поскольку команда возвращается до того, как осуществляется запись. Если система упадет до того, как данные будут записаны на диск, они потеряются и окажутся в несогласованном состоянии. К счастью, в 64-битном MongoDB включено журналирование.
Движки для хранения MMAPv1 и WiredTiger используют логирование для предотвращения этого, хотя WiredTiger может восстановиться до последней согласованной
Журналирование гарантирует, что база данных находится в согласованном состоянии после восстановления и хранит все данные до момента записи в журнале. Периодичность записей настраивается с помощью параметра
.
Чтобы быть уверенным в записях, убедитесь, что в файле конфигурации журналирование включено
, а периодичность записей соответствует тому объему информации, который вы можете позволить себе потерять.
Сортировка без индекса
При поиске и агрегировании часто возникает необходимость в сортировке данных. Будем надеяться, что это делается на одном из заключительных этапов, после фильтрации результата с целью уменьшения объема сортируемых данных. И даже в таком случае для сортировки вам понадобится
Если подходящего индекса нет, MongoDB обойдется без него. Существует ограничение памяти в 32 Мб на общий размер всех документов в
Поиск без поддержки индексов
Поисковые запросы выполняют функцию аналогичную операции JOIN в SQL. Для лучшей работы им нужен индекс значения ключа, используемого в качестве внешнего ключа. Это неочевидно, поскольку использование не отражено в explain()
. Такие индексы являются дополнением к индексу, записанному в explain()
, который в свою очередь используется операторами пайплайна $match
и $sort
, когда те встречаются в начале пайплайна. Индексы теперь могут охватывать любую стадию
Отказ от использования мультиобновлений
Метод
используется для изменения части существующего документа или целого документа, вплоть до полной замены в зависимости от заданного вами параметра
. Не так очевидно, что он не обработает все документы в коллекции, пока вы не установите параметр
для обновления всех документов, отвечающих критериям запроса.
Не забудьте о важности порядка ключей в хэш-таблице
В JSON объект состоит из неупорядоченной коллекции размером ноль или более пар имя/значение, где имя – это строка, а значение – это строка, число, логическое значение, ноль, объект или массив.
К сожалению, BSON придает большое значение порядку при поиске. В MongoDB порядок ключей внутри встроенных объектов { firstname: "Phil", surname: "factor" }
– это не то же самое, что { { surname: "factor", firstname: "Phil" }
. То есть вы должны хранить в документах порядок пар имя/значение, если хотите быть уверены в том, что найдете их.
Не путайте «null» и «undefined»
Значение «undefined» никогда не было допустимым в JSON, согласно $null
, что не всегда является хорошим решением.
Использование $limit()
без $sort()
Очень часто, когда вы ведете разработку в MongoDB, полезно просто увидеть образец результата, который вернется из запроса или агрегации. Для этой задачи вам пригодится $limit()
, но его никогда не должно быть в финальной версии кода, если только перед ним вы не используете $sort
. Эта механика нужна, поскольку иначе вы не можете гарантировать порядок результата, и не сможете надежно просматривать данные. В верхней части результата вы будете получать разные записи в зависимости от сортировки. Для надежной работы запросы и агрегации должны быть детерминированными, то есть выдавать одинаковые результаты при каждом выполнении. Код, в котором есть $limit()
, но нет $sort
, не будет являться детерминированным и впоследствии может вызвать ошибки, которые будет трудно отследить.
Заключение
Единственный способ разочароваться в MongoDB – это сравнивать ее непосредственно с другим типом баз данных, таким как СУБД, или прийти к ее использованию, исходя из каких-то определенных ожиданий. Это все равно что сравнивать апельсин с вилкой. Системы баз данных преследуют определенные цели. Лучше всего просто понять и оценить для себя эти различия. Было бы стыдно давить на разработчиков MongoDB из-за пути, который вынудил их идти по пути СУБД. Мне хочется видеть новые и интересные способы решения старых проблем, таких как обеспечение целостности данных и создание систем данных, устойчивых к сбоям и атакам злоумышленников.
Внедрение в MongoDB в версии 4.0 ACID transactionality — хороший пример внедрения важных улучшений инновационным путем. Мультидокументальные и мультиоператорные транзакции теперь атомарные. Также появилась возможность регулировать время, необходимое для получения блокировок, и заканчивать зависшие транзакции, а также изменять уровень изоляции.
Читать ещё:
Источник: habr.com