小编典典

MongoDB关系:嵌入还是引用?

sql

我是MongoDB的新手-来自关系数据库背景。我想设计一个带有一些注释的问题结构,但是我不知道该使用哪种关系进行注释:embed或reference?

一个带有一些注释的问题,例如stackoverflow,将具有以下结构:

Question
    title = 'aaa'
    content = bbb'
    comments = ???

首先,我想使用嵌入的注释(我认为embed在MongoDB中建议这样做),如下所示:

Question
    title = 'aaa'
    content = 'bbb'
    comments = [ { content = 'xxx', createdAt = 'yyy'}, 
                 { content = 'xxx', createdAt = 'yyy'}, 
                 { content = 'xxx', createdAt = 'yyy'} ]

显而易见,但我担心这种情况:如果要编辑指定的注释,如何获取其内容和问题?没有_id让我找到一个问题,也没有uestion_ref让我找到它的问题。(我真是个新手,如果不使用_idand我不知道有没有办法做到这一点question_ref。)

我必须ref不用embed吗?然后,我必须创建一个新的评论集吗?


阅读 305

收藏
2021-04-15

共1个答案

小编典典

更是一门艺术,而不是一门科学。关于模式的Mongo文档是一个很好的参考,但是这里有一些需要考虑的事项:

尽可能多地投入

Document数据库的乐趣在于它消除了许多Join。您的第一个本能应该是将尽可能多的内容放置在单个文档中。由于MongoDB文档具有结构,并且由于您可以在该结构中进行高效查询(这意味着您可以获取所需文档的一部分,因此文档大小不必担心太多),因此无需立即标准化数据您将使用SQL。特别是,除其父文档之外没有任何用处的数据都应属于同一文档。

可以从多个位置引用的数据分离到其自己的集合中。

这不是一个“存储空间”问题,而是一个“数据一致性”问题。如果许多记录将引用相同的数据,则更新单个记录并将引用保留在其他位置会更高效且更不会出错。

文件大小注意事项

MongoDB在单个文档上限制了4MB(16MB,1.8)的大小限制。在GB的数据世界中,这听起来很小,但它也是3万条推文或250个典型的Stack Overflow答案或20张闪烁的照片。另一方面,这比一次可能要在典型网页上呈现的信息要多得多。首先考虑什么会使您的查询更容易。在许多情况下,对文档大小的关注将是过早的优化。

复杂的数据结构:

MongoDB可以存储任意深度嵌套的数据结构,但不能有效地搜索它们。如果数据形成树,林或图,则实际上需要将每个节点及其边缘存储在单独的文档中。(请注意,还有一些专门针对此类数据设计的数据存储)

还指出了不可能返回文档中元素的子集。如果您需要挑选每个文档的一些位,则将它们分开会更容易。

数据一致性

MongoDB在效率和一致性之间进行权衡。规则是对单个文档的更改始终是 原子的,而对多个文档的更新则永远不应被认为是原子的。也没有办法“锁定”服务器上的记录(您可以使用“锁定”字段将其构建到客户端的逻辑中)。设计架构时,请考虑如何保持数据一致。通常,您在文档中保留的越多越好。

对于您要描述的内容,我将嵌入注释,并为每个注释提供一个带ObjectID的ID字段。ObjectID中嵌入了一个时间戳,因此您可以根据需要使用它而不是在上创建它。

2021-04-15