MongoDB - 子级和父级结构 [英] MongoDB - children and parent structure

查看:74
本文介绍了MongoDB - 子级和父级结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最近刚刚使用 MongoDB 深入研究了 NoSQL 的世界,但我仍在努力理解最好的架构方法,而无需第三次规范化数据然后加入它.目前我正在设计的项目是一个简单的文章集合,类似于维基.一篇文章将有一个标题和文本,以及(可能)一篇父文章和一篇或多篇子文章.

Having just recently delved into the world of NoSQL with MongoDB, I am still struggling to understand the best approach to architecture without 3rd normalizing the data and then joining upon it. Currently the project I am designing is a simple collection of articles, akin to a wiki. An article will have a title and text, as well as (possibly) a parent article and one or more children articles.

我对数据库设计有很多不同的想法,我想选择一个最符合 MongoDB 优势的想法.

I have had a number of differing ideas of for the database design and want to pick the one that best matches the strenghts of MongoDB.

想法一

由于数据库上最常见的查询类型总是简单地检索一篇文章,因此我嵌入了页面显示所有内容所需的所有相关数据.当然是实际的文章,以及带有 url (将匹配其他文档的 _id)以及 title 的父子文档,该文本是我们将在屏幕上打印标签内部.children 存在一个相同的结构,只是它是一个数组,因此所有 children 都在那里.

Since the most frequent type of query on the database will invariably be to simply retrieve an article, I am embedding all the relevant data that the page will need in order to display everything. The actual article of course, as well as a parent subdocument with a url (which will match the _id of some other document) as well as a title which is the text that we will print out on screen for inside of the tag. An identicle structure exists for the children except that it is an array so that all of the children are there.

{
        "_id" : "test-article-2",
        "title" : "Test Article 2",
        "text" : "Blah 2",
        "parent" : {
                "title" : "Test Article",
                "url" : "test-article"
        },
        "children" : [
                {
                        "title" : "Test Article 3",
                        "url" : "test-article-3"
                }
        ]
}

这种设计似乎具有速度优势(在我看来),但我想听听其他人对这种设计的看法.

This type of design seems to have the advantage of speed (in my opinion) but I would like to hear what others thing of this design.

想法二

我习惯于来自关系数据库世界.就是不将子对象嵌入到设计中,而只是简单地放入它们的唯一标识符.因此 parent 现在只包含一个文本字符串,它将与其他文档的 _id 匹配,并且 children 将类似地具有一个字符串数组,它们链接到_ids.

More along the lines that I am used to coming from a relational database world. would be to not embed sub-objects into the design but to simply put in their unique identifiers. Thus parent now contains just a text string which will match the _id of some other document, and children will similarly have an array of strings which link to _ids.

然而,为了获取所有信息以查看一篇文章,我们现在需要进行一些查询(至少我认为我们需要......)一个获取主要文章,然后另一个获取父母的标题用于放入标签,然后另一个以获取所有子文章并同样获取他们的标题.

In order to get all of the information to view an article however, we would now need to make a number of queries (at least I think we need to...) One to get the main article, then another to get the parent's title for putting in the tag and then another to get all of the children articles and likewise get their titles.

这似乎只是为了显示一篇文章而进行更多查询,但它可能使数据库的更新更容易,例如,如果某些文章被删除或更新.(再次不确定这一点).

This seems like a lot more querying just to display an article, but it may make the updating of the database easier, if for instance some article is deleted or updated. (again not sure on that point).

{
        "_id" : "test-article-2",
        "title" : "Test Article 2",
        "text" : "Blah 2",
        "parent" : "test-article",
        "children" : [ "test-article-3", "test-article-4"]
}

很高兴听到那些对 MongoDB 设计有更多经验的人的意见.

Would be glad to hear the input of those with more experience with MongoDB designing.

推荐答案

您需要考虑需要执行的查询类型以及需要每种类型的频率.当我在做类似的事情时,我想出了六种可能的行动:

You need to consider the type of queries you will need to perform and how frequently each type will be needed. When I was working on something similar, I came up with six possible actions:

  • 和父母一起做点什么
  • 和孩子们一起做点什么
  • 与祖先(父母的父母,父母的父母等)做一些事情
  • 对后代做一些事情(孩子的孩子,孩子的孩子等)
  • 更改关系(在层次结构中添加/移动/删除节点)
  • 更改当前节点中的主要数据(例如更改标题"字段中的值)

您需要估计每一项对您的应用程序的重要性.

You'll want to estimate how important each of these is to your application.

如果您的大部分工作都涉及处理某些给定文章的存储数据,包括其直接父级和子级,则第一个想法最有用.实际上,在 MongoDB 中,将您需要的所有信息放在同一个文档中而不是在外部引用它是很常见的,这样您只需要检索一件事并使用该数据即可.不过,列表中的最后四个操作更加棘手.

If most of your work involves working with stored data for some given article including its immediate parent and children, the first idea is most useful. Indeed in MongoDB, it is quite common to place all the information you need in the same document rather than referencing it externally so that you only need to retrieve one thing and just work with that data. The last four actions in the list are more tricky though.

特别是,在这种情况下,您需要遍历树以检索祖先和后代,在中间文档中移动并遵循路径,即使您可能只关心路径中的最后一个文档.对于长层次结构,这可能会很慢.由于每个文档中都存在所有数据,因此更改关系可能需要在多个文档中移动大量信息.但是即使更改像标题"这样的单个字段也可能很烦人,因为您必须考虑该字段存在于多个不同文档中的事实,无论是作为主字段还是在父字段或子字段下.

In particular, you will need to traverse through the tree to retrieve ancestors and descendants in this case, moving through intermediary documents and following a path, even though you may only care about the last document in the path. This can be slow for long hierarchies. Changing relationships can require moving a lot of information around in multiple documents because of all the data present in each one. But even changing a single field like "title" can be annoying, because you have to consider the fact that this field is present in multiple different documents, either as a main field or under the parent or children fields.

基本上,您的第一个想法在更多的静态应用程序中效果最佳它定期.

Basically, your first idea works best in more static applications where you won't be changing the data a lot after initially creating it, but where you need to read it regularly.

MongoDB 文档有 五种推荐的方法 用于处理树-像(分层)结构.它们都有不同的优点和缺点,尽管它们都可以很容易地更新一篇文章中的主要数据,只需在一个文档中进行更新.

The MongoDB documentation has five recommended approaches for handling tree-like (hierarchical) structures. All of them have different advantages and disadvantages, though they all make it easy to update the main data in an article by only needing to do so in one document.

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆