数据库分库分表的考量

1、什么时候考虑分库分表?

        阿里的《Java开发手册》上是说单表行数超过 500 万行或者单表容量超过 2GB,才推荐进行分库分表。
        其实这个数字也不是定死的,应该是根据具体的硬件情况来确定。我们可以通过调整INNODB_BUFFER_POOL_SIZE 来让MySQL有足够的内存来加载表的索引,那查询也没有太大的问题。而 INNODB_BUFFER_POOL_SIZE是依赖于服务器的硬件水平比如内存大小,一般占服务器内存的70%~80%左右(因为要给操作系统和其他应用留一部分内存),如果MySQL没有足够的内存一次性从磁盘中加载并储存表的索引,那么在查询的时候需要进行额外的磁盘IO来将索引读入内存,降低数据库的性能。因此,有时候改善服务器的硬件配置也能缓解SQL查询效率低的问题。
        分库分表一般是在经过优化索引、集群的读写分离等一系列优化之后,还存在查询效率不理想的情况下才进行的,如果业务数据量不大的话没必要这么折腾。

分库分表有水平切分和垂直切分2种方式,一般会先采用垂直切分,水平切分是大招。

2. 垂直切分

     垂直切分有垂直分库和垂直分表

2.1垂直分表

        垂直分表是将单表中的一部分“列”划分到另外一个表中。目的是为了减少SQL语句查询扫描的行数。那到底要将哪些列分离出来呢?

可以从这些角度考量:

  • 高频访问和低频访问的列,比如下图2.1的《用户信息表》的收货地址只有在购买配送的时候才会访问,相对于用户名和电话这些热点数据来说算是冷数据,可以将收货地址单独划分成一个表
  • 大文本字段 text、blob,收货地址它算是一个大文本字段,如果频繁在客户端和数据库中的网络中传输也不大合适。
  • 如果经常关联在一起查询的字段也没必要拆分,跨表跨库的join查询还是很麻烦的。

在这里插入图片描述
                                 图2.1

        一般来说,《用户信息表》中 1个用户有3个左右的收货地址,500万个用户大概就有1500万行记录。为了查询这500万个用户的信息,得扫描1500万行数据,无形之中就降低了查询的效率。并且,“收货地址”只有在购买配送的时候才会使用,相对用户登录等高频行为来说算是低频的行为。我们可以将用户信息这样的热点数据和查询相对少的“收货地址” 划分成2个表,划分之后,我们查询用户的信息的时候就可以减少SQL扫描的行数,没必要因为收货地址而去多扫描几行,提高查询效率。

2.2 垂直分库

        垂直分库划分的考量主要是要规划出一个相对独立的服务模块,像微服务的用户服务模块、商品模块、订单模块等。
在这里插入图片描述
                                  图2.2
        比如用户库可以划分为普通用户库、企业用户库,分别对应普通用户服务功能、企业服务功能,它们作为微服务中相对独立的业务功能,比如普通用户服务模块一般不会去访问企业用户数据库。

2.3 垂直切分优缺点

优点:

  1. 减少SQL扫描的行数,比如把“收货地址” 与用户信息热点数据分离出来,提高查询用户信息的效率
  2. 业务细分,将用户库划分为普通用户库和企业用户库,C端用户和企业用户办理的业务不完全相同,划分之后便于分级管理。

缺点:

  1. 跨库join查询比较麻烦
  2. 单个表的数据后期还是会很大。

3.水平切分

        当《用户表》(见图2.1右下)的用户记录膨胀到了1000万行,严重影响了查询的效率时,垂直分表也没有办法解决问题,我们就考虑进行水平切分。
        水平切分的常见策略有范围切分、hash切分等。

3.1 范围切分

        这种切分方式使用于数据行本身是有序的,比如说日志表(如下图3.1)就是按时间顺序创建的,可以根据create_time,查询的时候可以借助一个映射表来快速定位到哪个库的哪个表。

在这里插入图片描述

3.2 hash切分

        hash切分可以让热点数据均匀分布到各个库的表中,防止热点数据集中于单个库导致容易达到性能瓶颈。这种切分方式不要求数据本身是否有序,如果日志表采用hash切分让记录均匀分布的话反而查询不方便。
在这里插入图片描述具体的切分方式我借用了别人的图,划分的依据是

  1. 先选一个字段作为拆分依据,比如我用MEMBER_ID作为划分依据
  2. 然后 hash(MEMBER_ID) mod N,其中N是分库的数量或者划分表的数量,一般是取2的n次方,为了让数据均匀分布

       图中是以MEMBER_ID字段划分,预计要划分出1024个库,那么就通过hash(Pavarottil 7) mod 1024= 537来确定要划分到分库3里面。

        确定了在哪个数据库之后,要再确定划分到库里面的哪个表,也是采用同样的方法,先hash再取mod。

3.3 水平切分优缺点

优点:

  1. 解决单表数据量过大的问题
  2. 均匀分布的数据解决热点数据集中导致单个库压力大的问题

缺点:
跨库join查询效率比较差

        分库和分表的操作是可以结合进行的,可以划分为单库多表多库多表,垂直切分和水平切分也可两者结合使用。

猜你喜欢

转载自blog.csdn.net/qq_44384533/article/details/108433850
今日推荐