您的位置:首页 > 数据库 > MySQL

mysql分库分表方案浅析

2017-09-07 14:10 369 查看
分库分表(这里不讨论中间件)

分库:原因:单机负载高,优点:降低单机负载
分表:原因:单表读写压力大或者数据增长快,优点:使用多个表,提高读写效率

1、(代码)分表,即把一个很大的表达数据分到几个表中,这样每个表数据都不多。

                 优点:提高并发量,减小锁的粒度

                 缺点:代码维护成本高,相关sql都需要改动

2、(mysql)分区,所有的数据还在一个表中,但物理存储数据根据一定的规则存放在不同的文件中,文件也可以放到另外磁盘上

                    优点:代码维护量小,基本不用改动,提高IO吞吐量

                    缺点:表的并发程度没有增加

分表

在一个库中进行进行分表,有两种方法

1、mysql表分区(推荐)

使用表分区时,分区字段。需要根据业务来定,这里所说的业务,指的就是需要做分表的表会和哪些业务相关,

比如订单表,主键是订单ID,分表时,需要结合业务综合看待。

单纯就技术看:

如果按订单ID进行hash,操作分布多个表,但是在拓展时,就很麻烦

如果按订单ID进行范围range,操作集中某几个表,拓展时,很方便

综合结合看:

a,当业务需要根据时间来查询

如果按订单ID进行表分区,那么会造成查询无法走索引,导致全表扫描,效率低下,

如果按时间ID进行表分区,查询会走索引,但是时间都是按范围range,操作会集中几个表,读写压力就很明显

b,当业务需要查询用户某一时间段的订单

c,当业务需要.....

需要把所有业务都考虑进去

2、分表

分表的做法和表分区相同,不同的是需要在代码中实现这个功能。做法是先建立分表,然后在程序中写分表代码逻辑。

比如需要对订单表分表,代码中就会按订单ID(也可以任何字段)进行范围、或者hash取余计算该订单ID所处于的表,如果使用hash,可以使用一致性hash分表,避免hash取模方式在表增删时迁移全部数据。

同样,分表也需要集合业务,而且更加麻烦

单纯就技术看:

如果按订单ID进行hash,操作分布多个表,但是在拓展时,就很麻烦,需要把原来的数据再重新导入所有节点,这里很消耗时间,关键是导致系统很长的不可用时间

如果按订单ID进行范围range,操作集中某几个表,拓展时,很方便

这里和表分区的技术优缺点相同。

综合结合看:

a,当业务需要根据时间来查询

如果按订单ID进行表分区,无论是范围,还是Hash,都无法根据时间进行查询,只有全表扫描

如果按时间ID进行表分区,基本是按范围分表,可以定位时间范围。但是业务肯定会用订单ID来查询,而代码是根据时间ID做范围分表,等于说根据订单ID查询的业务就不可用了。

b,当业务需要查询用户某一时间段的订单

c,当业务需要.....

需要把所有业务都考虑进去

从这里可以看到,单纯做库内的分表,mysql自带的表分区适应度更高,分表的做法只适合于没有复杂的业务、多维度的查询。

一定要和业务结合起来,不然会遇到分了表后,业务无法运行的尴尬场面。

分库

在数据库中进行进行分库,有两个办法

1、代码分库

在代码中进行范围、或者hash取余计算该订单ID所处于的库,如果使用hash,最好是一致性hash分库,避免hash取模方式在节点增删时迁移全部数据。

单纯就技术看:

优点:计算简单,

缺点:增删库时,需要修改代码,并且需要迁移数据

2、单独建库建表,存放数据对应位置

单纯就技术看:

优点:可拓展性强

缺点:多次查询,效率低下,数据是否迁移看业务

综合结合看:
无论代码分库还是表存放位置,都存在跨库查询,已经分布式事务的问题,这里一定要综合业务,梳理流程,避免分布式事务。

分库分表

在数据库中进行进行分库分表,有两个办法

1、代码分库

a、代码分库+表分区

像这种组合的分库,一定要考虑到后期拓展的问题,如果是按范围,就没问题,直接增库,如果是按hash,就需要把所有的数据全部导出,再导入,时间代价很大。

优点:只需一层计算数据位置,表分区管理简单

缺点:需要迁移数据时,表分区较麻烦
这里没有写一致性hash分库+表分区,因为组合不能起到应有的效果。例如,分库使用一致性Hash,而表分区是hash,两边的算法不一致,数据无法对应, 就只能全部迁移了。

b、代码分库+分表

一种是hash分库 + hash分表,这个方法和上面的a方法相比,拓展时的都存在数据迁移时间过长,不同的是,a方法的表分区管理起来更简单。

一种是一致性hash分库 + 一致性hash分表,相比较,一致性Hash不易理解,有难度,迁移需要玩完备的方案,很繁琐,但是拓展时,只需要迁移部分数据即可。

优点:自由度高

缺点:多层计算,维护难度大
这里没有写一致性hash和hash分表的组合,因为[b]一致性hash要求算法一致。如果算法不同,在数据迁移时,很可能就会迁移全部数据,甚至数据混乱。[/b]

2、建库建表,存放数据对应的DB位置和表位置
注意:
分库分表中可能遇到跨库查询或者分布式事务的问题,比如用户ID为1的数据在库A,用户1的订单数据在库B,可以将用户1的关联订单数据在插入时选择用户1所在的库A,这样就能避免分布式查询和事务的问题。
来源:http://blog.csdn.net/stubborn_cow/article/details/50781310
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: