【问题标题】:MongoDB Alternative DesignMongoDB 替代设计
【发布时间】:2011-01-21 04:18:15
【问题描述】:

既然真的是not possible to return a single embedded document(尚未),那么什么是好的数据库设计替代方案?

这是一种情况。我有一个对象首先。 First 有一个 Second 对象数组。 Second 有一个 Third 对象数组。

db.myDb.findOne()
{
    "_id" : ObjectId("..."),
    "Seconds" : [
        {
            "Second Name" : "value",
            "Thirds" : [
                {
                    "Third Name" : "value" 
                }
            ]
        }
    ]
}

我有一个显示 First 对象列表的网站。您可以选择第一个对象,它将带您进入显示第一个详细信息的页面,其中包括第二个对象的列表。如果您选择第二个对象,则会发生同样的事情。

当打开第三个页面时,查询获取单个 First 对象似乎是不正确的,然后一些如何深入代码以获取正确的第三个对象的数据。直接获取一个 Third 对象会容易得多,可能是通过 _id。

也许我仍然太困在 SQL 领域,但在这种情况下,我的想法是为每种类型创建一个集合并让它们相互引用,因为我需要从树中获取单个对象,并且不要像在非网络应用程序中那样在每个请求中保留对对象的引用。

这是否是解决此问题的正确方法,还是我只是在文档领域没有清楚地思考?

【问题讨论】:

    标签: architecture schema mongodb


    【解决方案1】:

    我认为这取决于使用情况。如果您经常需要访问没有包含 'First' 的 'Second' 或 'Third' 项目,那么最好不要被嵌入。

    我用来帮助我确定某些东西是否可以更好地嵌入的一个问题是问自己它是它的一部分还是与之相关。例如,“First”实际上是否包含一个或多个“Seconds”(等等),或者它们是分开的事物,恰好以某种方式相关?从表面上看,我会说博客 post 包含 cmets(除非您迫切需要在不了解这些帖子的情况下查询 cmets 列表),但是user/author 可能不包含帖子列表,而是它们会以某种方式链接但位于不同的集合中。

    使用DBRef 可以在MongoDB 中实现跨集合关系。这是一种特殊类型,用于描述与另一个对象的关系。如果您的项目确实属于它们自己的集合,它们可以有一个 DBRef 指向彼此之间。这些可以按照您想要的方式进行(即,它们在 First 中的集合,或者每个 Second 可以有一个首先指向其父级)。

    示例 1 - 每个父级都有一组子引用:

    db.firsts.findOne()
    {
        "_id" : ObjectId("..."),
        "Seconds" : [
            { $ref : 'seconds', $id : <idvalue> },
            { $ref : 'seconds', $id : <idvalue> },
            { $ref : 'seconds', $id : <idvalue> }
        ]
    }
    
    db.seconds.findOne()
    {
        "_id" : ObjectId("..."),
        "Second Name" : "value",
        "Thirds" : [
            { $ref : 'thirds', $id : <idvalue> },
            { $ref : 'thirds', $id : <idvalue> }
        ]
    }
    
    db.thirds.findOne()
    {
        "_id" : ObjectId("..."),
        "Third Name" : "value"
    }
    

    示例 2 - 每个孩子都有对其父母的引用

    db.firsts.findOne()
    {
        "_id" : ObjectId("...")
    }
    
    db.seconds.findOne()
    {
        "_id" : ObjectId("..."),
        "First" : { $ref : 'firsts', $id : <idvalue> }
        "Second Name" : "value",
    }
    
    db.thirds.findOne()
    {
        "_id" : ObjectId("..."),
        "Second" : { $ref : 'seconds', $id : <idvalue> }
        "Third Name" : "value"
    }
    

    大部分MongoDB language drivers has a way of dealing with dbrefs 比在控制台上更简洁(通常使用某种“DBRef”类)。以这种方式工作将意味着您有更多的数据库请求,但如果它对您的应用程序有意义,那么它可能是一个公平的折衷方案 - 特别是如果您的示例中的“秒”或“三”列表通常是需要的或交互的关键使用系统或其功能。

    第二种方法最类似于您使用传统的关系数据库。 MongoDB 的美妙之处在于,它允许您在真正有意义的时候以关系方式工作,而不是在没有意义的时候。非常灵活,最终取决于您的数据和应用程序,什么对您有意义。最终,您应该使用哪种方法的问题的答案取决于您的应用程序及其存储的数据 - 我们无法从您的示例中看出这一点。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-27
      • 2011-02-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多