我已经阅读了基于文档的dbs的描述,例如,如果您愿意,可以在帖子的同一文档中将所有评论嵌入到帖子中:
{
_id = sdfdsfdfdsf,
title = "post title"
body = "post body"
comments = [
"comment 1 ......................................... end of comment"
.
.
n
]
}
Run Code Online (Sandbox Code Playgroud)
我的情况类似,每个评论可能大到8KB,每个帖子可能多达30个.
即使在同一文档中嵌入注释很方便,我想知道是否有大型文档影响性能,尤其是当MongoDb服务器和http服务器在不同的机器上运行并且必须通过LAN进行通信时?
在其他人之后发布这个答案所以我将重复上面提到的一些事情.请接受第一个合适的答案,而不是这个答案.
那说有几件事需要考虑.考虑以下三个问题:
如果可以回答所有问题,那么您可以嵌入comments数组.在所有其他场景中,您可能需要一个单独的集合来存储您的评论.
首先,您可以以并发安全的方式实际更新和删除注释(请参阅使用位置运算符的更新),但有些事情是您无法做到的,例如基于索引的插入.
将嵌入式阵列用于任何类型的大型集合的主要问题是移动更新问题.MongoDB为db.col.stats().paddingFactor每个文档保留一定量的填充(请参阅),以允许它根据需要增长.如果它用完了这个填充(并且它通常在你的用例中),它将不得不移动磁盘上不断增长的文档.这使得更新速度降低了一个数量级,因此是高带宽服务器的一个严重问题.一个相关但但不那么重要的问题是带宽.如果您别无选择,只能查询整个帖子及其所有评论,即使您只显示前10条,也会浪费相当多的带宽,尤其是云环境中的问题(您可以使用$切片以避免其中的一些).
如果你想嵌入这里是你的基本操作:
添加评论 :
db.posts.update({_id:[POST ID]}, {$push:{comments:{commentId:"remon-923982", author:"Remon", text:"Hi!"}}})
Run Code Online (Sandbox Code Playgroud)
更新评论:
db.posts.update({_id:[POST ID], 'comments.commentId':"remon-923982"}, {$set:{'comments.$.text':"Hello!"}})
Run Code Online (Sandbox Code Playgroud)
删除评论
db.posts.update({_id:[POST ID], 'comments.commentId':"remon-923982"}, {$pull:{comments:{commentId:"remon-923982"}}})
Run Code Online (Sandbox Code Playgroud)
所有这些方法都是并发安全的,因为更新标准是(进程范围)写锁定的一部分.
尽管如此,你可能想要一个专门的收藏品供你评论,但还有第二选择.您可以将每个评论存储在专用文档中,也可以使用评论桶,例如每个评论20-30条(详见http://www.10gen.com/presentations/mongosf2011/schemascale).这有利有弊,因此您可以自行决定哪种方法最适合您想要做的事情.如果你的评论每篇文章的评论可能会超过几百,因为你需要的跳过(N)光标方法的o(N)性能,我会去寻找桶.在所有其他情况下,只需对每个文档方法进行评论.对于其他用例的评论查询也是最灵活的.
这在很大程度上取决于您想要允许的操作,但单独的集合通常更好。
例如,如果您想允许用户编辑或删除评论,将评论存储在单独的集合中是一个非常好的主意,因为这些操作很难或不可能单独使用原子修饰符来表达,并且状态管理变得很痛苦。该文档还涵盖了这一点。
嵌入评论的一个关键问题是您将拥有不同的作者。通常,博客文章只能由博客作者修改。可以说,通过嵌入的注释,读者还可以获得对对象的写访问权限。
像这样的代码会很危险:
post = db.findArticle( { "_id" : 2332 } );
post.Text = "foo";
// in this moment, someone does a $push on the article's comments
db.update(post);
// now, we've deleted that comment
Run Code Online (Sandbox Code Playgroud)
简短的回答:是的,也不是。
假设您正在写一个基于 mongoDB 的博客。您可以将您的评论嵌入到您的帖子中。
原因:查询很容易,您只需执行一次请求即可获取需要显示的所有数据。
现在,您知道您将获得带有子文档的大型文档。由于您需要通过 LAN 为它们提供服务,我强烈建议您将它们存储在不同的集合中。
原因:通过网络发送大型文档需要时间。我想,在某些情况下,您不需要每个子文档。
TL;DR:两种变体都有效。我建议您将评论存储在单独的表中。
| 归档时间: |
|
| 查看次数: |
6445 次 |
| 最近记录: |