数据库 MySQL 中多对多关系怎样进行 Scale

ShiningRay · 2012年07月08日 · 最后由 ShiningRay 回复于 2012年07月09日 · 4280 次阅读

我这里做的有几个场景 一个是记录用户阅读过哪些文章,另一个场景是tag 当关系表中记录达到几千万条的时候,读取插入性能都急剧下降,这时候该如何优化呢?

共收到 11 条回复

是否可以将这种关系保存在redis中?

垂直拆分或者水平拆分

#2楼 @Rei 求详细,怎样是垂直怎样是水平呢?

#2楼 @Rei 水平拆分好理解,垂直拆分的话似乎已经没有什么可拆的了,把tagging放到单独的服务器上? 而且水平拆分应该怎样进行,比如我既想知道这个用户读过哪些文章,又想知道这篇文章哪些用户读过

#1楼 @chucai 保存在redis中也涉及到如何scale的吧

#3楼 @reducm 垂直拆分是按功能划分,比如新闻和博客都用了Tag,那么把这两个功能的Tag拆开。水平拆分是按照时间段/用户名/其他分区方法把一张表拆开。我不熟拆表,不过看网上的资料说到SQL的扩展大都这样。

#4楼 @ShiningRay 这篇文章被哪些用户读过一定需要查出全部吗?如果不是,可以做一个小的队列缓存。

#6楼 @Rei 感谢,之前一直不太懂水平和垂直的问题,原来维度就是以表的角度

10M这个数量级就要sharding了吗?用memcache和redis当缓存撑不住?

@ShiningRay 你这种需求属于对于many-to-many的中间表做水平切分,并且对双向的many都需要查询,常见做法是建立2个表,以用户阅读文章为例,一个表根据user_id做切分(hash or range shard),另外一个表根据topic_id做切分,index在2个表上分开对user_id和topic_id来建立。创建新记录的时候,需要往这2张表都要插入一样的数据。查询的时候,先看是从哪个方向的many来查询,然后再做普通的shard db lookup.

啊哈,楼上正解,如果真到那个量级,不过save的时候就得做两次了

#8楼 @bhuztez 未雨绸缪,嗯

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册