Понимание ограничения размера документа MongoDB BSON
Вопрос
Из MongoDB окончательное руководство:
Документы, превышающие 4 МБ (при преобразовании в BSON), не могут быть сохранены в базу данных. Это несколько произвольный предел (и может быть поднят в будущем); В основном это предотвращение плохого дизайна схемы и обеспечения последовательной производительности.
Я не понимаю этого предела, означает ли это, что документ, содержащий сообщение в блоге с большим количеством комментариев, которые оказались больше, чем 4 МБ, не может храниться в виде единого документа?
Также это также считается вложенными документами?
Что если я хотел документ, который проверяет изменения в значении. (Это в конечном итоге может расти, превышая предел 4 МБ.)
Надеюсь, кто -то это правильно объяснит.
Я только начал читать о MongoDB (первая база данных NOSQL, о которой я узнаю).
Спасибо.
Решение
Во -первых, это на самом деле поднимается в следующей версии, чтобы 8MB
или же 16MB
... но я думаю, что чтобы представить это в перспективе, Элиот из 10gen (который разработал MongoDB), выражает это лучше всего:
РЕДАКТИРОВАТЬ: Размер был официально «поднят», чтобы 16MB
Итак, в вашем блоге, 4MB на самом деле очень много. http://www.gutenberg.org/etext/36
Если ваш пост в блоге так долго с таким количеством комментариев, я, например, не собираюсь читать его :)
Для трекбэков, если вы посвятили им 1 МБ, вы можете легко иметь более 10 тысяч (вероятно, ближе к 20K)
Так что, кроме действительно странных ситуаций, это будет работать отлично. И, в случае исключения, или спама, я действительно не думаю, что вам в любом случае вам понадобится объект 20 МБ. Я думаю, что ограничение трекбэков как 15 тысяч или около того имеет большой смысл, независимо от того, что для производительности. Или, по крайней мере, особый корпус, если это произойдет.
-Элиот
Я думаю, что вам будет довольно трудно достичь предела ... и со временем, если вы обновите ... вам придется беспокоиться все меньше и меньше.
Основной момент лимита в том, что вы не используете всю ОЗУ на своем сервере (поскольку вам нужно загрузить все MB
S документа в RAM, когда вы запросите его.)
Таким образом, лимит составляет несколько % обычного использования оперативной памяти в общей системе ... что будет продолжать расти год за годом.
Примечание о хранении файлов в MongoDB
Если вам нужно хранить документы (или файлы) больше, чем 16MB
Вы можете использовать Gridfs API который автоматически разбивает данные на сегменты и передает их обратно к вам (тем самым избегая проблемы с ограничениями размера/оперативной памяти).)
Вместо хранения файла в одном документе Gridfs делит файл на части или куски, и хранит каждый кусок в качестве отдельного документа.
Gridfs использует две коллекции для хранения файлов. В одной коллекции хранятся файлы, а другой хранит метаданные файла.
Вы можете использовать этот метод для хранения изображений, файлов, видео и т. Д. В базе данных, как вы могли бы в базе данных SQL. Я использовал это, чтобы даже хранить несколько гигабайтовых видеофайлов.
Другие советы
Многие в сообществе не предпочли бы никаких ограничений с предупреждениями о производительности, см. Этот комментарий для хорошо обоснованного аргумента:https://jira.mongodb.org/browse/server-431?focusedCommentId=22283&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-22283
Мое мнение, ведущие разработчики упрямы по поводу этой проблемы, потому что они решили, что это важная «функция» на ранней стадии. Они не собираются менять его в ближайшее время, потому что их чувства ранены, что кто -то поставил под сомнение. Еще один пример личности и политики, отвлекаясь к продукту в сообществах с открытым исходным кодом, но это не на самом деле неприятная проблема.
Чтобы опубликовать здесь разъяснительный ответ для тех, кто будет направлен здесь Google.
Размер документа включает в себя все в документе, включая подразделения, вложенные объекты и т. Д.
Итак, документ:
{
_id:{},
na: [1,2,3],
naa: [
{w:1,v:2,b:[1,2,3]},
{w:5,b:2,h:[{d:5,g:7},{}]}
]
}
Имеет максимальный размер 16 мг.
Sbudocuments и вложенные объекты все учитываются в размере документа.
Я еще не видел проблемы с пределом, который не включал большие файлы, хранящиеся в самом документе. Уже существует множество баз данных, которые очень эффективны для хранения/извлечения больших файлов; Они называются операционными системами. База данных существует как слой над операционной системой. Если вы используете решение NOSQL по соображениям производительности, почему вы хотите добавить дополнительные накладные расходы на доступ к вашим данным путем размещения уровня DB между вашим приложением и вашими данными?
JSON - это текстовый формат. Итак, если вы обращаетесь к своим данным через JSON, это особенно верно, если у вас есть двоичные файлы, потому что они должны быть закодированы в Uuencode, Hexadecimal или Base 64. Путь преобразования может выглядеть как
Бинарный файл <> json (кодированный) <> bson (кодированный)
Было бы более эффективно поместить путь (URL) в файл данных в вашем документе и сохранить сами данные в двоичном файле.
Если вы действительно хотите сохранить эти файлы неизвестной длины в своем БД, то вам, вероятно, было бы лучше поместить их в Gridfs и не рисковать убийством вашего параллелизма, когда доступ к большим файлам.
Вложенная глубина для документов BSON:MongoDB поддерживает не более 100 уровней гнездования для документов BSON.
Возможно, хранение поста в блоге -> Комментарии связь В нереляционной базе данных на самом деле не лучший дизайн.
В любом случае, вы должны хранить комментарии в отдельной коллекции для сообщений в блоге.
редактировать
См. Комментарии ниже для дальнейшего обсуждения.
Согласно с https://www.mongodb.com/blog/post/6-rules-thumb-for-mongodb-schema-design-part-1
Если вы ожидаете, что сообщение в блоге может превышать лимит документа 16 МБ, вы должны извлечь комментарии в отдельную коллекцию и ссылаться на сообщение в блоге из комментария и выполнить соединение на уровне приложения.
// posts
[
{
_id: ObjectID('AAAA'),
text: 'a post',
...
}
]
// comments
[
{
text: 'a comment'
post: ObjectID('AAAA')
},
{
text: 'another comment'
post: ObjectID('AAAA')
}
]