Это действительно важный вопрос в Монго, и ответ - это скорее искусство, чем наука. Наличие одной коллекции, полной гигантских документов, определенно является анти-паттерном, потому что оно работает против многих функций Монго.
Например, при извлечении документов вы можете извлечь только весь документ из коллекции (не совсем верно, но в основном). Поэтому, если у вас есть огромные документы, вы каждый раз извлекаете огромные документы. Кроме того, наличие огромных документов делает сегментирование менее гибким, поскольку только документы верхнего уровня индексируются (и, следовательно, обрабатываются) в каждой коллекции. Вы можете индексировать значения глубоко в документе, но значение индекса связано с документом верхнего уровня.
В то же время, использование чисто реляционных отношений также является анти-паттерном, потому что вы потеряли большую часть ссылочной целостности, перейдя в Монго. Кроме того, все объединения выполняются в памяти приложения, поэтому для каждого из них требуется полный возврат (медленно).
Так что ответ - сделать что-то среднее. Я думаю, вы, вероятно, захотите коллекцию для частных лиц и другую коллекцию для бизнеса в этом случае. Я говорю это потому, что кажется, что у бизнеса достаточно метаданных, связанных с ним, чтобы их можно было собрать много. (Кроме того, у меня индивидуальные деловые отношения кажутся многим многим). Однако у индивидуума может быть объект Name
(со свойствами first
и last
). Было бы плохой идеей сделать Name отдельным сборником.
Некоторая информация от 10gen о дизайне схемы: http://www.mongodb.org/display/DOCS/Schema+Design
EDIT
Кроме того, Mongo имеет ограниченную поддержку транзакций - в форме атомарных агрегатов. Когда вы вставляете объект в монго, весь объект либо вставляется, либо не вставляется. Таким образом, домен вашего приложения требует согласованности между определенными объектами, вы, вероятно, хотите сохранить их в одном документе / коллекции.
Например, рассмотрим приложение, которое требует, чтобы User
всегда имел объект Name
(содержащий FirstName
, LastName
и MiddleInitial
). Если User
было каким-либо образом вставлено без соответствующего Name
, данные будут считаться поврежденными. В СУБД вы должны обернуть транзакцию вокруг операций, чтобы вставить User
и Name
. В Mongo мы уверены, что Name
находится в том же документе (агрегированном), что и User
, чтобы достичь того же эффекта.
Ваш пример немного менее ясен, так как я не понимаю бизнес-кейсы. Одна вещь, которая действительно приходит на ум, - то, что Mongo имеет превосходную поддержку наследования. Возможно, имеет смысл поместить всех пользователей, отдельных лиц и, возможно, компаний в одну коллекцию (в зависимости от того, как моделируется приложение). Если у одного человека много контактов, вы, вероятно, хотите, чтобы у него был массив идентификаторов. Если ваше приложение требует быстрого предварительного просмотра контактов, вы можете подумать о дублировании части лица и сохранении массива объектов контактов.
Если вы привыкли думать о РСУБД, вы, вероятно, думаете, что все ваши данные всегда должны быть согласованными. Правда, это, вероятно, не совсем верно. Эта концепция применения атомных агрегатов к домену в последнее время активно проповедуется сообществом DDD. Если вы посмотрите на свой домен подробно, как это делают ваши бизнес-пользователи, границы согласованности должны стать четкими.