这些天我在工作中使用MongoDB。到目前为止,我觉得这是一次很棒的经历。
但是我被要求用MongoDB建立集合之间的关系。这违背了NoSQL概念的目的,但在这个领域是一个很好的老菜鸟,我来找其他意见。
例如,如果我们采用共同的角色/用户关系,是否可以拥有一个名为“Roles”的引用集合,并将一个项目的引用归属于User项目?
我开始考虑创建一个为所请求的对象提供ID的对象,但感觉就像我不应该对NoSQL这样做。
那么有没有人要求做同样的事情?你成功了,怎么样?
答案 0 :(得分:17)
MongoDB(以及大多数其他NoSQL数据库)本身并不支持关系概念。 RDBMS具有本机查询工具,用于定义和利用MongoDB缺少的关系(例如,JOIN)。
这并不意味着您无法在NoSQL数据库中定义关系/引用。它只是意味着没有可识别关系的本机查询运算符。
在MongoDB中,有三种不同的方法可以“引用”另一个文档:
将引用文档的ID(通常是ObjectId)存储为引用文档中的字段。如果您的应用程序知道必须查找引用文档的集合,这是最佳方法。 Example : {_id: ObjectId(...); userId: ObjectId(...) <- reference).
第二种方法是使用DBRef约定,该约定以正式方式定义对文档的引用:{ $ref : <collname>, $id : <idvalue>[, $db : <dbname>] }
。在几乎所有情况下,第一种方法都是首选,但DBRef确实允许引用文档,应用程序可能不知道其类型或位置。有关此处的详细信息:http://www.mongodb.org/display/DOCS/Database+References#DatabaseReferences-DBRef以及有关何时在此处使用它们的详细信息:http://valyagolev.net/article/mongo_dbref/
从技术上讲,它不是一个参考,但在很多情况下,将(部分)文档嵌入到其他文档中是有意义的。请注意,使用NoSQL数据库时,模式的规范化应该不那么重要。 Example : {_id: ObjectId(...); user: {_id: ObjectId(...), name:"Willy Wonka"}}
。
所有这一切,你可以在MongoDB中使用完全规范化的模式,大多数ORM库将为你做很多非MongoDB原生的工作。在大多数情况下,这确实意味着您最好使用传统的RDBMS。如果您正在切换到MongoDB,因为您认为它是MySQL的快速版本,那么您就会被误导。两者都有功能性甜点,只有有限的重叠。如果您的应用程序严重依赖关系功能,请不要使用NoSQL。
其他值得阅读的文章可让您快速了解非关系思维: http://www.mongodb.org/display/DOCS/Schema+Design
答案 1 :(得分:3)
我会这样做:
db.permissions {
"Admins" : { "Users" : ["Peter", "Tom"], "Privilages": "rw" },
"Supervisors" : { "Users" : ["Tom", "Brad", "Angelina"], "Privilages": "w" },
...
}
你在重复自己不是NoSQL结构中的问题。归一化不是最佳选择。
或者,您可以将每个成员的$ _id存储在“Users”数组中,并让用户在其单独的集合中使用其名称,电话等。另一种选择是将用户文档存储在“Users”数组中,但管理起来可能会很麻烦。