数据库设计 - mongodb文章和评论放在同一条数据里效率怎样?
黄舟
黄舟 2017-04-21 10:57:50
0
2
625

将评论和文章放在一起,这里我有一个疑问,当评论数量很大以后,会不会导致在查询文章列表页的时候效率低下?
如果将comments剥离到另一个collection里,这样是不是能缓解只显示文章列表的情况下的压力

{
	"_id" : ObjectId(),
	"author" : "",
	"comment_num" : "",
	"comments" : [
		{
			"text" : "",
			"created" : ISODate(),
			"author" : ""
		},
	],
	"created" : ISODate(),
	"text" : "",
	"title" : ""
}
黄舟
黄舟

人生最曼妙的风景,竟是内心的淡定与从容!

Antworte allen(2)
大家讲道理

@halty 说得很好,不完全同意他的观点。如果评论不多,放在一起的设计很合适,楼上说得很好。但是如果评论多了,问题就来了。最重要的有两基本出发点: 1. 硬盘太慢; 2. 只要数据在内存里,就没问题。

  1. find
    数据特别大了之后,在磁盘上读好多数据,因为Memory Mapped File都会放在内存里,可是我们只需要里面的一小部分,最主要的问题是可能OS会把别的数据换页到硬盘上。单就列出文章列表来说,内存就没有被有效地利用。
  2. insert
    在磁盘文件上,如果一个document一直长啊长,好多次,这不是一个好事。因为 如果新加入数据后,比如加了一个新评论,document变大了,原来的地方放不下了,就要找新的地方,以前的空洞会被重新利用。但是问题是,document位置变了,所有跟它有关的索引都要变。如果你还有个数组上的索引,比如发表评论的用户名,那更新的索引就跟这个数组长度成线性关系。
  3. size
    楼上在这点上说得很好。16MB的上限。

综上,评论特别多的时候,会影响性能。

总结,schema设计要考虑

  1. 数据规模,经常访问的数据只要在内存里,对访问来说没什么问题。上面第一条find里提到的内存利用不充分,其实不是大问题。因为热门文章的评论总有不少人看,放内存里也不错。如果document一直长呀长,MongoDB会自动地在分配磁盘空间时多分配一些。
  2. 与Access Pattern相适应。写评论相对看文章看评论,太小了,Twitter的数据是平均发tweet 5K/s, 读timeline 300K/s. 60倍呀!只要读请求在内存里能满足就好了。用MongoDB就可以不用另搞caching了。不是访问真得特别大,写特别多这样极端的情况,都好说。真得到了那一天,MongoDB的sharding就派上用场了。
  3. 开发方便 产品的成本不仅仅是机器硬件、网络的成本,更重要的是程序员的开发成本,工资都那么高……所以,写着快捷方便,不容易出错也是很重要的一点,对不?这也就解释了为什么MongoDB文档模型的灵活性广受好评了。

话说回来了,我觉得绝大多数这类应用的评论都不会过百吧……这时候单文档就发挥出优势了,几百评论都没问题的,题主的问题就不是问题了。希望题主的应用能突破这个数……

左手右手慢动作

首先确认一点:当评论数量很大以后,不大会导致在查询文章列表页的时候效率低下。你可以再指定查询结果集的document只返回部分field的数据(需要注意的是,如果对这种只包含部分field数据的document进行更新再保存时,有可能会出错),推荐这样做,能够很好的节省网络带宽。

此外,目前mongodb对于单个document的大小是有限制的,如果评论数量过多时,会有可能超过document的默认大小限制,这个时候就需要剥离comment了。

Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage