分库分表的算法有哪些?都有哪些优缺点?

提问者:帅平 问题分类:面试刷题
分库分表的算法有哪些?都有哪些优缺点?
5 个回答
羡风不停留
羡风不停留
预定义算法
预定义算法是事先已经明确知道分库和分表的数量,可以直接将某类数据路由到指定库或表中,查询的时候亦是如此。
发布于:2个月前 (03-04) IP属地:未知
青山依旧
青山依旧
地理位置分片算法
地理位置分片其实是一个更大的范围,按城市或者地域划分,比如华东、华北数据放在不同的分片库、表。
发布于:2个月前 (03-04) IP属地:未知
绿水长流
绿水长流
范围 + 取模算法
为了避免热点数据的问题,我们可以对上范围算法优化一下
这次我们先通过范围算法定义每个库的用户表t_user只存1000w数据,第一个db_order_1库存放userId从1 ~ 1000w,第二个库1000~2000w,第三个库2000~3000w,以此类推。


每个库里再把用户表t_user拆分成t_user_1、t_user_2、t_user_3等,对userd进行取模路由到对应的表中。
有效的避免数据分布不均匀的问题,数据库水平扩展也简单,直接添加实例无需迁移历史数据。
发布于:2个月前 (03-04) IP属地:未知
泛白的记忆使沉迷
泛白的记忆使沉迷
范围限定算法
范围限定算法以某些范围字段,如时间或ID区拆分。
用户表t_user被拆分成t_user_1、t_user_2、t_user_3三张表,后续将user_id范围为1 ~ 1000w的用户数据放入t_user_1,1000~ 2000w放入t_user_2,2000~3000w放入t_user_3,以此类推。按日期范围划分同理。

优点:
单表数据量是可控的
水平扩展简单只需增加节点即可,无需对其他分片的数据进行迁移

缺点:
由于连续分片可能存在数据热点,比如按时间字段分片时,如果某一段时间(双11等大促)订单骤增,存11月数据的表可能会被频繁的读写,其他分片表存储的历史数据则很少被查询,导致数据倾斜,数据库压力分摊不均匀。
发布于:2个月前 (03-04) IP属地:未知
人潮似海遇见你°
人潮似海遇见你°
取模算法
关键字段取模(对hash结果取余数 hash(XXX) mod N),N为数据库实例数或子表数量)是最为常见的一种路由方式。
以t_order订单表为例,先给数据库从 0 到 N-1进行编号,对 t_order订单表中order_no订单编号字段进行取模hash(order_no) mod N,得到余数i。i=0存第一个库,i=1存第二个库,i=2存第三个库,以此类推。
同一笔订单数据会落在同一个库、表里,查询时用相同的规则,用t_order订单编号作为查询条件,就能快速的定位到数据。

优点:
实现简单,数据分布相对比较均匀,不易出现请求都打到一个库上的情况。

缺点:
取模算法对集群的伸缩支持不太友好,集群中有N个数据库实·hash(user_id) mod N,当某一台机器宕机,本应该落在该数据库的请求就无法得到处理,这时宕掉的实例会被踢出集群。
此时机器数减少算法发生变化hash(user_id) mod N-1,同一用户数据落在了在不同数据库中,等这台机器恢复,用user_id作为条件查询用户数据就会少一部分。
发布于:2个月前 (03-04) IP属地:四川省
我来回答