数据库:我都快爆了,你为什么还不分库分表?( 二 )


如上图,商城系统包括主页 Portal 模板、用户模块、订单模块、库存模块等,所有的模块都共有一个数据库,通常数据库中有非常多的表 。
因为用户量不大,这样的架构在早期完全适用,开发者可以拿着 demo到处找(骗)投资人 。
一旦拿到投资人的钱,业务就要开始大规模推广,同时系统架构也要匹配业务的快速发展 。
多应用单数据库
在前期为了抢占市场,这一套系统不停地迭代更新,代码量越来越大,架构也变得越来越臃肿,现在随着系统访问压力逐渐增加,系统拆分就势在必行了 。
为了保证业务平滑,系统架构重构也是分了几个阶段进行 。
第一个阶段将商城系统单体架构按照功能模块拆分为子服务,比如:Portal 服务、用户服务、订单服务、库存服务等 。

数据库:我都快爆了,你为什么还不分库分表?

文章插图
 
多应用单数据库
如上图,多个服务共享一个数据库,这样做的目的是底层数据库访问逻辑可以不用动,将影响降到最低 。
多应用多数据库
随着业务推广力度加大,数据库终于成为了瓶颈,这个时候多个服务共享一个数据库基本不可行了 。我们需要将每个服务相关的表拆出来单独建立一个数据库,这其实就是“分库”了 。
单数据库的能够支撑的并发量是有限的,拆成多个库可以使服务间不用竞争,提升服务的性能 。
数据库:我都快爆了,你为什么还不分库分表?

文章插图
 
多应用多数据库
如上图,从一个大的数据中分出多个小的数据库,每个服务都对应一个数据库,这就是系统发展到一定阶段必要要做得“分库”操作 。
现在非常火的微服务架构也是一样的,如果只拆分应用不拆分数据库,不能解决根本问题,整个系统也很容易达到瓶颈 。
分表
说完了分库,那什么时候分表呢?
如果系统处于高速发展阶段,拿商城系统来说,一天下单量可能几十万,那数据库中的订单表增长就特别快,增长到一定阶段数据库查询效率就会出现明显下降 。
因此,当单表数据增量过快,业界流传是超过500万的数据量就要考虑分表了 。当然500万只是一个经验值,大家可以根据实际情况做出决策 。
那如何分表呢?
分表有几个维度,一是水平切分和垂直切分,二是单库内分表和多库内分表 。
1)水平拆分和垂直拆分
就拿用户表(user)来说,表中有7个字段:id,name,age,sex,nickname,description,如果 nickname 和 description 不常用,我们可以将其拆分为另外一张表:用户详细信息表,这样就由一张用户表拆分为了用户基本信息表+用户详细信息表,两张表结构不一样相互独立 。但是从这个角度来看垂直拆分并没有从根本上解决单表数据量过大的问题,因此我们还是需要做一次水平拆分 。
数据库:我都快爆了,你为什么还不分库分表?

文章插图
 
拆分表
还有一种拆分方法,比如表中有一万条数据,我们拆分为两张表,id 为奇数的:1,3,5,7……放在 user1,id 为偶数的:2,4,6,8……放在 user2中,这样的拆分办法就是水平拆分了 。
水平拆分的方式也很多,除了上面说的按照 id 拆表,还可以按照时间维度去拆分,比如订单表,可以按每日、每月等进行拆分 。
  • 每日表:只存储当天的数据 。
  • 每月表:可以起一个定时任务将前一天的数据全部迁移到当月表 。
  • 历史表:同样可以用定时任务把时间超过 30 天的数据迁移到 history表 。
总结一下水平拆分和垂直拆分的特点:
  • 垂直切分:基于表或字段划分,表结构不同 。
  • 水平切分:基于数据划分,表结构相同,数据不同 。
2)单库内拆分和多库拆分
拿水平拆分为例,每张表都拆分为了多个子表,多个子表存在于同一数据库中 。比如下面用户表拆分为用户1表、用户2表 。
数据库:我都快爆了,你为什么还不分库分表?

文章插图
 
单库拆分
在一个数据库中将一张表拆分为几个子表在一定程度上可以解决单表查询性能的问题,但是也会遇到一个问题:单数据库存储瓶颈 。
所以在业界用的更多的还是将子表拆分到多个数据库中 。比如下图中,用户表拆分为两个子表,两个子表分别存在于不同的数据库中 。


推荐阅读