小编典典

MongoDB 关系:嵌入还是引用?

all

我是 MongoDB的新手——来自关系数据库背景。我想设计一个带有一些评论的问题结构,但我不知道评论使用哪种关系:embed或者reference

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

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让我找到一个,也没有question_ref让我找到它的问题。(我是新手,我不知道没有_idand有没有办法做到这一点question_ref。)

我必须使用refnotembed吗?然后我必须为评论创建一个新集合?


阅读 98

收藏
2022-03-06

共1个答案

小编典典

这更像是一门艺术而不是一门科学。Mongo Documentation on
Schemas
是一个很好的参考,但这里有一些事情需要考虑:

  • 尽可能多地投入

文档数据库的乐趣在于它消除了许多连接。您的第一直觉应该是尽可能多地放在一个文档中。因为 MongoDB
文档具有结构,并且您可以在该结构中有效地查询(这意味着您可以获取所需的文档部分,所以文档大小不应该让您太担心)没有立即需要规范化数据,例如你会在 SQL
中。特别是,除了其父文档之外无用的任何数据都应该是同一文档的一部分。

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

这与其说是“存储空间”问题,不如说是“数据一致性”问题。如果许多记录将引用相同的数据,那么更新单个记录并在其他地方保留对它的引用会更有效且更不容易出错。

  • 文档大小注意事项

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

  • 复杂的数据结构:

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

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

  • 数据一致性

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

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

2022-03-06