mongoDB处理1-nnn关系的最佳做法是什么?

在关系型数据库中,1-nn关系意味着2个或更多的表。 但是在mongoDB中,因为可以直接将这些东西存储到如下的模型中:

Article{ content: String, uid: String, comments:[Comment] } 

我对如何pipe理这些关系感到困惑。 例如,在文章评论模型中,我是否应该直接将所有评论存储到文章模型中,然后每次将整个文章对象读出为JSON? 但是如果评论增长真的很大呢? 就像在文章对象中有1000条评论一样,这样的策略是否会使GET过程每次都很慢?

我绝不是这方面的专家,但是我以前曾经经历过类似的情况。

从我看过的几个演示中,你应该直接存储所有的评论。 这将给你最好的performance(除非你期望有一些荒谬的评论)。 这样你就可以在你的文件中拥有一切。

在未来,如果事情开始进展顺利,你注意到事情进展缓慢,你可以做一些事情。 您可以查看存储最新(插入任意数量)的评论,并引用其他评论的存储位置,然后将旧评论映射到“存储桶”中以保持加载时间的快速。

但是最初我会把它存储在一个文件中。

所以会有一个模型,看起来可能是这样的:

 Article{ content: String, uid: String, comments:[ {"comment":"hi", "user":"jack"}, {"comment":"hi", "user":"jack"}, ] "oldCommentsIdentifier":12345 } 

然后只有oldCommentsIdentifier填充,如果你确实移动评论的评论string,但我真的不会这样做less于1000评论,甚至更多。 要在这里进行一些testing,看看这个“甜蜜”的地方是什么。

我认为答案的很大一部分取决于你期望的评论数量。 有一个文件包含一个可以增长到任意大的数组是一个坏主意,由于几个原因。 首先, $push操作符往往会很慢,因为它经常会增加文档的大小,迫使它被移动。 其次,最大BSON大小为16MB,所以最终你将无法再增长arrays。

如果您希望每篇文章都有大量的评论,您可以创build一个单独的“评论”集合,其中每个文档都有一个“article_id”字段,其中包含与其绑定的文章的_id(或uid,或一些其他领域的独特的文章)。 通过查询“articles_id”字段与文章的_id匹配的任何文档的“comments”集合,这将使得检索特定文章的所有评论变得容易。 索引这个字段会使查询速度非常快。

作为对您的问题的评论发表的链接,也是关于模式devise的一般提示的一个很好的参考。

但是,如果用_id连接文章和注释来解决这个问题,是不是还会回到关系数据库devise呢? 不知何故失去了成为NoSQL的本质?

不是,NoSQL不是全部关于embedded模型。 事实上embedded应该仔细考虑你的情况。

确实,聚合框架解决了从embedded对象所需的许多问题,您需要将它们用作文档本身。 我定义了需要用作文档的子文档,如下所示:

  • 需要在界面中分页的文档
  • 跨多个根文档可能存在的文档
  • 需要在组内进行高级sorting的文档
  • 当在一个组中的文件将超过根文件16meg的限制

正如我所说,聚合框架确实解决了这个问题,但是您仍然在寻找一个实时或接近的查询,就像在SQL中对相同数量的文档执行相同的查询。

这种效果并不总是令人满意的。

您可以使用$ slice操作符来实现正常查询的分段(有点)的分段,但是这样可能会遇到与在大型结果集上使用skip()limit()相同的问题,这也是不可取的,因为您不能使用范围查询来修复它很容易(聚合框架将再次需要)。 即使有1000个子文档,我也看到了速度问题,不仅仅是我,还有其他人。

那么让我们回到原来的问题:如何pipe理模式。

现在你不会喜欢的答案是:这一切都要依靠。

你的意见是否满足他们应该分开的需求? 是这样的,可能是一个很好的select。

没有最好的办法。 在MongoDB中,您应该根据将要使用它的应用程序来devise您的集合。

如果您的应用程序需要显示文章的评论,那么我可以说最好将这些评论embedded文章collections。 否则,您将最终与您的数据库几次往返。

有一种情况下embedded不起作用。 据我所知,在MongoDB中文档大小限制在16MB。 实际上这是相当大的。 但是,如果您认为文档大小可能超过此限制,则最好分开收集。