mysql分库分表方案浅析

分库分表(这里不讨论中间件)

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


分表
在一个库中进行进行分表,有两种方法
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、代码分库+表分区 优点:只需一层计算数据位置,表分区管理简单 缺点:需要迁移数据时,表分区较麻烦 b、代码分库+分表 优点:自由度高 缺点:多层计算,维护难度大 2、建库建表,存放数据对应的DB位置和表位置
相关文章
相关标签/搜索