Mongo DB Design, встраивание и взаимосвязь - PullRequest
21 голосов
/ 28 сентября 2010

Я строю простую учетную систему, в которой у пользователя много счетов.Теперь я пытаюсь решить, должна ли банкнота быть собственной коллекцией или вложенной в пользователя.Я склоняюсь к первому, но я НИКОГДА не делал ничего такого, что связано с NoSQL, поэтому я просто иду методом проб и ошибок, и то, что я думаю, имеет для меня смысл.

Я понимаю, что у Mongo есть ограничение на размер документа 4 МБ, и это заставляет меня думать, что у меня должна быть отдельная коллекция для счетов, так как они будут накапливаться ежедневно и в конечном итоге могут занимать много места.

Я просто ищу мнения по этому вопросу.По сути, я буду запрашивать счета пользователя между разными периодами дат (как вы можете себе представить, чтобы это делала система учета).

Не то, чтобы это действительно имело значение, но я использую Mongoid в проекте Rails3.Я подумал, что сделаю что-то вроде:

class User
  references_many :bills
end

class Bill
  referenced_in :user
end

Любые комментарии или предложения по дизайну с благодарностью.

Ответы [ 3 ]

24 голосов
/ 28 сентября 2010

1) Что касается предела документов 4 МБ, то, что сказано в «MongoDB: Полное руководство»:

Документы размером более 4 МБ (при преобразовании в BSON) не могут быть сохранены в базе данных.Это несколько произвольный предел (и может быть повышен в будущем);это в основном предотвращает неправильное проектирование схемы и обеспечивает стабильную производительность.Чтобы увидеть размер BSON (в байтах) документа doc , запустите Object.bsonsize ( doc ) из оболочки.

Чтобы дать вам представление о том, как4МБ, весь текст Война и мир составляет всего 3,14МБ.

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

2) Денормализованная схема (счета идут вместе с пользовательским документом) - это путь, если вы знаете, что никогда не будетезапускать глобальные запросы к счетам (например, если вы хотите получить десять последних счетов, введенных в систему).Вам придется использовать map-lower для получения результатов для таких запросов, если вы используете денормализованную схему.

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

Учитывая упомянутый вами вариант использования, я бы остановился на-нормализованная схема.

3) Все обновления в MongoDB являются атомарными и сериализованными.Это должно ответить на беспокойство Стива.

Вы можете найти эти слайды полезными.http://www.slideshare.net/kbanker/mongodb-meetup

Вы также можете заглянуть на страницу развертывания продукции MongoDB.Слайды SF.net могут оказаться полезными.

1 голос
/ 12 июля 2011

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

Насколько я понимаю, документ объемом 4 МБ был расширен до 16 МБ в версиях 1.8+. Это было из видео-презентации Банкира, который является одним из членов MongoDB. Я НЕ проверил это значение, но беру на себя его слово (так как он, надеюсь, знает, о чем говорит).

Что касается вопроса о том, что происходит, когда несколько обновлений происходят у одного и того же пользователя со встроенными счетами ... опять же из одной и той же видеопрезентации, при условии, что MongoDB обновляет информацию так быстро, что обычно это не проблема. Экземпляр MongoDB заблокирован во время обновления, поэтому многократные обновления не должны быть проблемой.

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

Лично я обнаружил, что MongoDB (и базы данных NoSQL) полезны для особых случаев, но традиционные SQL / RDMS все еще лучше для большинства проблем. Если вы являетесь кем-то вроде Craigslist, и изменение схемы занимает у вас 2 месяца для запуска ваших архивных данных, тогда да, MongoDB и NoSQL имеют смысл. но для подавляющего большинства приложений я не думаю, что обработка такого количества данных будет серьезной проблемой.

1 голос
/ 28 сентября 2010

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

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

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

...