MongoDB关系:嵌入还是引用?
我是MongoDB的新手 - 来自关系数据库背景。 我想用一些评论来设计一个问题结构,但我不知道使用哪种关系进行评论: embed
或reference
?
有些评论的问题,比如stackoverflow,会有这样的结构:
Question
title = 'aaa'
content = bbb'
comments = ???
起初,我想使用嵌入式评论(我认为在MongoDB中推荐embed
),如下所示:
Question
title = 'aaa'
content = 'bbb'
comments = [ { content = 'xxx', createdAt = 'yyy'},
{ content = 'xxx', createdAt = 'yyy'},
{ content = 'xxx', createdAt = 'yyy'} ]
它很清楚,但我担心这种情况: 如果我想编辑一个特定的评论,我如何获得它的内容和它的问题? 没有_id
让我找到它,也没有question_ref
让我找到它的问题。 (我很新手,我不知道是否有任何方法可以在没有_id
和question_ref
情况下执行此操作。)
我必须使用ref
没有embed
? 那么我必须创建一个新的评论集合?
这是一门艺术而不是一门科学。 关于Schema的Mongo文档是一个很好的参考,但这里有一些需要考虑的事情:
尽可能多地放入
文档数据库的乐趣在于它消除了大量的联接。 你的第一本能应该尽可能多地放在单个文件中。 由于MongoDB文档具有结构,并且因为您可以在该结构中有效地进行查询(这意味着您可以获取所需的文档部分,因此文档大小不应该太担心),因此不需要对数据进行标准化你会在SQL中。 特别是除了母文档之外没有用的任何数据应该是同一文档的一部分。
将可以从多个地方引用到自己的集合中的数据分开。
这不是一个“存储空间”问题,因为它是一个“数据一致性”问题。 如果许多记录都会引用相同的数据,那么更高效且更少错误更新单个记录并在其他地方保留引用。
文档大小的考虑
MongoDB在单个文档上添加了4MB(16MB和1.8)的大小限制。 在GB数据世界中,这听起来很小,但它也是3万个推文或250个典型的堆栈溢出答案或20个闪烁照片。 另一方面,这是比一次想要在典型网页上呈现的信息多得多的信息。 首先考虑一下会让你的查询更容易。 在许多情况下,关于文档大小的问题将不成熟。
复杂的数据结构:
MongoDB可以存储任意深度的嵌套数据结构,但无法高效地进行搜索。 如果您的数据形成树,森林或图形,则实际上需要将每个节点及其边缘存储在单独的文档中。 (请注意,有些数据存储专门为此类数据设计,因此也应该考虑)
还有人指出,要在文档中返回一部分元素是不可能的。 如果您需要挑选每个文档的几个位,将它们分开更容易。
数据一致性
MongoDB在效率和一致性之间进行权衡。 规则是对单个文档的更改始终是原子性的,而对多个文档的更新永远不应被认为是原子性的。 也无法“锁定”服务器上的记录(可以使用例如“锁定”字段将其构建到客户端的逻辑中)。 在设计模式时,考虑如何保持数据的一致性。 一般来说,您保存在文档中的内容越多越好。
对于你所描述的内容,我会嵌入评论,并给每个评论一个带有ObjectID的id字段。 ObjectID中嵌入了时间戳,所以如果你喜欢,你可以使用它来代替创建。
如果我想编辑指定的评论,如何获取其内容和问题?
您可以通过子文档查询: db.question.find({'comments.content' : 'xxx'})
。
这将返回整个问题文档。 要编辑指定的评论,您必须在客户端上找到评论,进行编辑并将其保存回数据库。
一般来说,如果你的文档包含一个对象数组,你会发现这些子对象需要修改客户端。
一般来说,如果你在实体之间有一对一或一对多的关系,那么嵌入是很好的,如果你有多对多的关系,引用是很好的。
链接地址: http://www.djcxy.com/p/86403.html