【问题标题】:Is it possible to have relation between object in a MongoDB database?是否可以在 MongoDB 数据库中的对象之间建立关系?
【发布时间】:2011-08-09 09:52:21
【问题描述】:

这些天我在工作中使用 MongoDB。到目前为止,我觉得这是一次很棒的体验。

但是,我被要求在集合之间建立与 MongoDB 的关系。这违背了 NoSQL 概念对我来说的目的,但作为该领域的老菜鸟,我来征求其他意见。

例如,如果我们采用常见的角色/用户关系,是否可以有一个名为“角色”的引用集合并将一个项目的引用归因于用户项目?

我开始考虑创建一个对象,该对象为请求的对象提供 ID,但感觉我不应该与 NoSQL 有任何关系。

那么这里有人被要求做同样的事情吗?你成功了吗?如何成功?

【问题讨论】:

    标签: mongodb mongodb-.net-driver


    【解决方案1】:

    MongoDB(和大多数其他 NoSQL 数据库)本身并不支持关系的概念。 RDBMS 具有本地查询工具来定义和利用 MongoDB 缺乏的关系(例如 JOIN)。

    这并不意味着您不能在 NoSQL 数据库中定义关系/引用。这只是意味着没有可感知关系的本机查询运算符。

    在 MongoDB 中有三种不同的方式可以从另一个文档中“引用”一个文档:

    1. 将引用文档的 ID(通常是 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 原生的工作。在大多数情况下,这确实意味着您最好使用传统的 RDBMS。如果您因为认为它是 MySQL 的快速版本而切换到 MongoDB,那么您就被误导了。两者都有功能甜蜜点,只有有限的重叠。如果您的应用严重依赖关系功能,请不要使用 NoSQL。

    其他值得阅读的文章可以让您快速了解非关系思维: http://www.mongodb.org/display/DOCS/Schema+Design

    【讨论】:

    • 谢谢。我想我会选择第一个解决方案(不过我会尝试第二个),然后我会实现 manager 来获得我想要的对象。
    【解决方案2】:

    我会这样做:

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

    在 NoSQL 结构中重复自己不是问题。归一化不是它的最佳选择。

    或者,您可以只将每个成员的 $_id 存储在“Users”数组中,并将用户及其姓名、电话……放在单独的集合中。另一种选择是将用户文档存储在“Users”数组中,但这可能会导致管理繁琐。

    【讨论】:

    • 我个人对重复也有同样的想法,但我不能确定数据库大小对性能的影响。感谢您的提示。
    • 不确定这是否是对该数据进行最常见操作的最佳模式(即,用户 X 是否具有权限 Y)。这更有效,因为它避免了数组上的索引:db.admins {name:.., roles:[..,..,..]}。我也不会使用整数特权级别,因为某些角色是互斥的。取决于应用程序。
    • @Remon van Vliet:这只是一个示例以及权限。它应该说明设置。我可能也不会使用二进制权限,但这是我想出的最短的方法。
    猜你喜欢
    • 1970-01-01
    • 2023-02-01
    • 2016-08-02
    • 1970-01-01
    • 2011-03-08
    • 2014-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多