分库分表作为一种常见的数据库设计,本文尝试梳理相关知识。主要脉络如下:
1、没有分库分表之前遇到了什么问题
2、怎么做分库分表
3、分库分表之后带来的影响(弊端)
一、单库单表存在的问题
对于小规模的业务,一个数据库里面通常会有 user、order、product 表,每个表里面都包含大量的字段。在用户还比较少,访问不多的时候,单库单表不存在问题。
随着业务的发展,用户访问次数变多,一张表的字段甚至可能达到几十上百,数据库的查询压力就开始出现了。根据阿里《Java开发手册》,在单表行数超过500万行或者单表容量超过2GB的时候MySQL的性能就会开始下降。如果在这样的数据库里面进行关联查询,查询速度就更慢了
(1)单表太大:一张表里面字段和数据太多,查询困难
(2)单库太大:一个库里面的表很多,磁盘空间装不下,IO次数多,CPU忙不过来
这个时候就要开始考虑如何解决问题了。
二、主从复制
当单库单表性能不足时,通常首先考虑的应该是读写分离。大多数情况数据库的情况都是读操作远大于写操作,把读和写两种操作分别放到主库(master)和从库(Slave)两种库上面,主库负责写数据,从库负责读数据,从库从主库同步数据,保存数据一致。
这样可以有效提高数据库的性能,操作也比较简单。当然这个架构也存在着弊端
(1)写操作拓展困难。需要保证多个主库数据一致性
(2)复制延时:主从库同步需要时间
(3)锁表率上升:读写分离,命中率少,锁表的概率提升
(4) 表变大,缓存率下降
此时的主从复制还是单库单表,只不过复制了很多份并进行同步。如果业务量继续增加,还是会再次遇到瓶颈。这个时候就要考虑新的解决方案:分库分表
三、分库分表
分库分表核心思路并不复杂:一个不够就用两个,把数据分别放到多个表或者库当中。具体做法上可以通过水平切分和垂直切分
1、分表
(1)垂直分表
如果表中的字段比较多,可以将一些不常用的、数据较多的拆分到「拓展表」。垂直分表之后单表的大小会减少但行数不变
(2)水平分表
水平分表则是按照某种规则,把一张表的数据放到同一个库里面的多个表内。每张表的字段是相同的,但单表的数据量减少了
2、分库
(1)垂直分库
一个数据库的表太多,可以按照一定的业务逻辑进行垂直切分。比如把用户相关的表放在一个数据库,把商品相关的表放在另一个数据库。然后两个数据库分别放在不同服务器上,此时磁盘空间、内存、TPS的瓶颈都能得到解决
(2)水平分库
水平分库在操作上比较麻烦:将一张表的数据切分到多个服务器上,每个服务器有相同的库和表,只是里面的数据不一样。
四、分库分表的弊端
(1)联合查询困难
分表之后如果还在同一个数据库就还好,如果在不同数据库的话就非常困难了
(2)事务支持
数据库本身提供了事务管理功能,但分库分表之后就需要自己支持分布式事务了,编码难度增加
(3)结果合并麻烦
比如对订单表进行了拆分,要查询某商品的订单时就需要对多个表的结果进行合并,比较麻烦