1

我正在构建一个电子学习应用程序,并将学生活动显示为时间线,我应该将它们嵌入到user集合中,还是使用userId.

约束:

  • 一对多的关系。
  • 用户活动详细且数量众多
  • 在 90% 的情况下,我们一次只需要查看一个用户,另一种情况是主管(老师)需要查看用户活动的摘要(可能是另一个集合?)
  • 搜索活动和找学生的用例我还没想过,也许我以后会有这个用处?(例如,看看谁先完成了某些特定活动?但这会将关系更改为多对多,这是一个完全不同的问题)

我在这两个问题中找到了相关问题的不同模式:

4

2 回答 2

2

这两篇文章都是对的,也都是错的。

嵌入还是不嵌入?这始终是关键问题,它取决于您的需求、查询和存储,甚至是您的工作集。

归根结底,我们只能给出一些你实际上无法告诉你哪个最好的建议。

但是,考虑到活动提要的大小,我个人不会嵌入它,因为它很容易增长到超过 16meg(每个用户),但是对于查询的速度和能力,您可以汇总用户的最后 20 个活动,然后嵌入进入用户行(因为最后 20 个通常是查询最多的)。

但是随后嵌入聚合取决于,分片可以处理查询巨大的水平缩放集合,并且使用正确的查询意味着您不会从嵌入中获得任何真正的好处,并且可能通过维护索引、存储和维护该子文档所需的查询。

至于嵌入到死亡的地步。目前很多 MongoDB 的查询主要依赖于一层或两层嵌入,这就是为什么很难维护 12 个嵌套表的原因,此时您开始在这里看到问题以及如何维护这样的 Google 小组一个巨大的文件(如果你真的想,答案是客户端)。

在 90% 的情况下,我们一次只需要查看一个用户,另一种情况是主管(老师)需要查看用户活动的摘要(可能是另一个集合?)

考虑到这一点,我将在用户上进行聚合,这意味着用户可以通过一次往返单独查看自己或其他用户的活动。

但是,考虑到老师很可能必须拥有来自所有用户的页面结果,我将存放一个单独的活动集合并为他们查询。对子文档的聚合进行分页需要一些查询,在这种情况下,最好这样做。

希望这能让你开始。

于 2012-11-29T08:25:17.320 回答
1

您不应将活动嵌入到学生文档中。

我对此非常有信心的原因是以下陈述:

“用户活动详细且数量众多”
“将学生活动显示为时间线”
“老师需要查看用户活动的摘要”

设计具有不断增长的文档的模式是一种不好的做法 - 因此,每次完成/添加另一个活动时,让学生文档不断增长是导致性能不佳的原因。

如果要对学生的活动进行排序,如果每个活动都是活动集合中的单独文档,则比学生文档中的数组要简单得多。

当您需要查询多个学生的活动时,将所有活动放在一个集合中会变得微不足道,但是将活动嵌入到学生文档中会变得很困难(您很可能需要聚合框架,这会使其速度变慢)。

您还说您将来可能需要“查看谁先完成了某些特定活动?但这会将关系更改为多对多,并且是一个完全不同的问题”-事实并非如此。您不需要将其视为多对多关系 - 您仍然可以存储与单个用户关联的多个活动,然后查询匹配活动“X”的所有记录,按完成时间(或其他)排序并查看哪个学生时间最短。

于 2012-11-29T20:44:22.400 回答