数据库分库分表那些事儿

103 阅读3分钟

这是我参与11月更文挑战的第2天,活动详情查看:2021最后一次更文挑战

前言

在业务初期,我们的数据量不大,业务运行平稳。有一天,报警群突然就出现了慢查询警告,这时候,我们通常的做法是优化 SQL 语句,添加索引,优化索引,然后大功告成,问题解决。但是,随着业务的进一步发展,数据量增大到一定程度,前面的几个手段都不在好使,此时此刻,恰如彼时彼刻,是时候祭出我们的分库分表了。
分库分表,就是将表拆分,减少单表数据量,从而提高数据库效率。

垂直分表

垂直分表,就是将一张表垂直拆分成多个表。通常做法就是就是将常用的列(热点列)抽离出来作为一张新表,然后将不常用的列抽成另一张对前面主表的扩展表。举个例子,我们的原来有一张表 table(id, A, B, C, D),然后我们垂直分表为主表 table_a(id_a, A, B) 与拓展表 table_b(id_b, C, D, table_a_id)。垂直分表的核心在于:

  1. 冷热分离,热点数据作为主表,不常用数据作为主表的扩展表信息。
  2. 大的字段独立存储,比如这个字段存储的是一个 marshal 之后的信息。
  3. 关联比较紧密的列需要放在一张表中。 垂直分表带来的好处有:
  4. 降低了锁表的几率,如操作 table_a 与操作 table_b 互不冲突
  5. 提高了热点数据的操作效率,比如 table_a 的效率不会被 table_b 的操作所拖累。

水平分表

水平分表,就是将一张表的按照一定的规则拆分成多个表,比如按照表的一个枚举字段,根据枚举值区分不同的表。水平分表带来的好处有:

  1. 将数据量过大的表,拆分为数据量较小的多个表,每一个表都只包含少量数据,提升了检索性能。
  2. 降低了锁表的几率。

垂直分库

垂直分库,就是按照业务本身将表进行分类,属于同一业务的表放在一个库里面,不同的库可以放在不同的服务器上面,就是专库专用,类似于微服务,每个服务的 DB 库都不相同。垂直分库的好处包括:

  1. 在业务层面进行数据库解耦
  2. 在高并发场景下,垂直分库在一定程度上有利于解决 IO、数据库连接数等瓶颈。
  3. 支持对不同业务数据进行不同级别的监控、维护等。

水平分库

水平分库就是按照一定规则将表的数据拆到不同的数据库中,每个数据库可以放在不同的服务器上。水平分库解决了单表数据量过大的问题,从理论上解决了高并发的瓶颈。但是水平分库需要解决以下几个核心问题:

  1. 数据在哪一个库里?利用一致性哈希算法,我们可以解决这个问题。
  2. 查询结果如何合并?利用 fork-join 模式并发执行程序,提高效率。
  3. 全局唯一主键 ID?可以利用数据库编号来构成主键 id,也可以利用不少现成的全局唯一 id 生成方案。