在了解MongoDB中的性能和架构设计之后,我仍然无法弄清楚当性能是必须的时候如何在应用程序中进行架构设计。
让我们想象一下,如果我们必须让YouTube与MongoDB一起使用它作为数据库。你会如何制作架构?
选项1 :两个集合(视频集和评论集合)
优点:添加,删除和修改评论只会影响评论集合,因此这些操作会更有效。
缺点:检索视频和评论将是对数据库的2个不同查询,一个用于视频,一个用于评论。
选项2 :单一收藏(嵌入评论的视频集)
专业人士:您只需一次查询即可检索视频及其评论。
缺点:添加,删除和修改评论会影响视频文档,因此这些操作的效率会降低。
那你觉得怎么样?我的猜测是真的吗?
答案 0 :(得分:3)
作为沙漠中的来电者,我不得不说嵌入应该只在非常特殊的情况下使用:
我写了an article about the above,更详细地描述了各自的问题。
此外,我认为对视频发表评论没有任何好处。要回答的问题是
请注意,此处视频和评论之间的唯一连接是关于给定视频,因此您已经拥有_id
或其他内容来确定视频。此外,您不希望一次加载所有评论,特别是如果您有很多评论,因为这会因为加载时间过长而降低UX。
我们说它是_id
。因此,通过它,您可以轻松地分页评论:
db.comments.find({"video_id": idToFind})
.skip( (page-1) * pageSize )
.limit( pageSize )
HTH
答案 1 :(得分:1)
通常答案是,这取决于。根据经验,您应该支持嵌入,除非您需要自己定期查询嵌入对象或者嵌入式数组可能变得太大(> ~100条记录)。使用本指南,您需要询问有关申请的一些问题。
您的应用程序如何访问数据?您是否只会在与相关视频相同的页面上显示评论?或者,您是否希望提供选项以显示所有电影中给定用户的所有评论?第一个场景有利于嵌入(一个集合),而在第二个场景中你可能会更好地使用两个集合。
其次,您对每个视频有多少评论?以IMDB为例,您可以轻松期望对流行视频发表100多条评论,这意味着您最好创建两个独立的集合,因为嵌入式评论数组会很快变大。我不太关心应用程序连接的开销,与关系数据库中的服务器端连接相比,它们的速度通常相当,前提是您的集合已正确编入索引。
最后,用户在首次发帖后多久更新一次评论?如果您在5分钟后锁定评论,就像在StackOverflow上一样,用户可能不会经常更新他们的评论。在这种情况下,更新或删除视频集合中的评论的开销可以忽略不计,甚至可能超过在单独的评论集合中执行第二个查询的成本。
答案 2 :(得分:0)
您应该使用嵌入式以获得更好的性能。你的I / O会更小。在最坏的情况下?将文档保存在数据库中可能需要一些时间,但它不会花费太多时间来检索它。
根据您的应用需求,您应该对读取持久性进行妥协,反之亦然。
因此,明智地选择您的数据库非常重要。