Подтвердить что ты не робот

Mongo DB Design, встраивание vs отношений

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

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

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

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

class User
  references_many :bills
end

class Bill
  referenced_in :user
end

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

4b9b3361

Ответ 1

1) Что касается предела документа 4 МБ, это то, что говорит "MongoDB: The Definitive Guide":

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

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

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

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

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

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

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

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

Вы также можете посмотреть страницу MongoDB Production Deployments. Вы можете найти слайды SF.net.

Ответ 2

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

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

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

Ответ 3

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

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

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

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

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