Возможно ли иметь связь между объектом в базе данных MongoDB? - PullRequest
12 голосов
/ 09 августа 2011

Я использую MongoDB на работе в эти дни. Пока что я нахожу это отличным опытом.

Однако меня просят установить отношения между коллекциями с MongoDB. Для меня это противоречит цели концепции NoSQL, но, будучи старым добрым нубом в этой области, я пришел спросить другие мнения.

Например, если мы возьмем общие отношения Роль / Пользователь, возможно ли иметь коллекцию ссылок с именем «Роли» и приписать ссылку одного элемента на элемент пользователя?

Я начал думать о создании объекта, который предоставляет идентификатор запрашиваемому объекту, но мне кажется, что я не должен иметь ничего общего с NoSQL.

Так есть ли здесь люди, которых просили сделать то же самое? Удалось ли вам и как?

Ответы [ 2 ]

17 голосов
/ 09 августа 2011

MongoDB (и большинство других баз данных NoSQL) изначально не поддерживают концепцию отношений. СУБД имеют собственные инструменты запросов для определения и использования отношений (например, JOIN), которых нет в MongoDB.

Это не означает, что вы не можете определить отношения / ссылки в базах данных NoSQL. Это просто означает, что нет собственных операторов запросов, поддерживающих отношения.

В MongoDB существует три разных способа «ссылки» на один документ из другого:

  1. Сохраните идентификатор упомянутого документа (обычно ObjectId) как поле в ссылочном документе. Это лучший подход, если ваше приложение будет знать, в какой коллекции оно должно искать указанный документ. Example : {_id: ObjectId(...); userId: ObjectId(...) <- reference).

  2. Второй подход заключается в использовании соглашения DBRef, которое определяет ссылку на документ в формализованном виде: { $ref : <collname>, $id : <idvalue>[, $db : <dbname>] }. Почти во всех случаях предпочтителен первый подход, но DBRef разрешает ссылки на документы, в которых приложение может не знать тип или расположение. Более подробная информация здесь: http://www.mongodb.org/display/DOCS/Database+References#DatabaseReferences-DBRef и хорошее прочтение о том, когда использовать их здесь: http://valyagolev.net/article/mongo_dbref/

  3. Технически не является ссылкой, но во многих случаях имеет смысл встраивать (части) документов в другие документы. Обратите внимание, что нормализация вашей схемы должна быть менее сфокусирована на базах данных NoSQL. Example : {_id: ObjectId(...); user: {_id: ObjectId(...), name:"Willy Wonka"}}.

Все это говорит о том, что вы можете использовать полностью нормализованную схему в MongoDB, и большинство библиотек ORM сделают для вас большую часть работы, которая не является родной для MongoDB. В большинстве случаев это означает, что вам будет лучше с традиционной СУБД. Если вы переходите на MongoDB, потому что думаете, что это быстрая версия MySQL, вы были дезинформированы. Оба имеют функциональные сладости с ограниченным наложением. Если ваше приложение сильно зависит от реляционной функциональности, не используйте NoSQL.

Другие статьи, которые стоит прочесть, чтобы научить вас нереляционному мышлению: http://www.mongodb.org/display/DOCS/Schema+Design

3 голосов
/ 09 августа 2011

Я бы сделал это так:

db.permissions {
 "Admins" : { "Users" : ["Peter", "Tom"], "Privilages": "rw" },
 "Supervisors" : { "Users" : ["Tom", "Brad", "Angelina"], "Privilages": "w" },
 ...
}

То, что вы повторяете себя, не является проблемой внутри структуры NoSQL. Нормализация не является оптимальной для этого.

В качестве альтернативы, вы можете просто сохранить $ _id каждого члена в массиве «Users», чтобы пользователи с их именами, phone, ... находились в отдельной коллекции. Другой вариант - хранить пользовательские документы в массиве «Users», но это может быть неудобно для администрирования.

...