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


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

文章插图
 
多库拆分
一句话总结:分表主要是为了减少单张表的大小,解决单表数据量带来的性能问题 。
分库分表带来的复杂性
既然分库分表这么好,那我们是不是在项目初期就应该采用这种方案呢?不要激动,冷静一下,分库分表的确解决了很多问题,但是也给系统带来了很多复杂性,下面简要说一说 。
跨库关联查询
在单库未拆分表之前,我们可以很方便使用 join 操作关联多张表查询数据,但是经过分库分表后两张表可能都不在一个数据库中,如何使用 join 呢?
有几种方案可以解决:
  • 字段冗余:把需要关联的字段放入主表中,避免 join 操作;
  • 数据抽象:通过ETL等将数据汇合聚集,生成新的表;
  • 全局表:比如一些基础表可以在每个数据库中都放一份;
  • 应用层组装:将基础数据查出来,通过应用程序计算组装;
分布式事务
单数据库可以用本地事务搞定,使用多数据库就只能通过分布式事务解决了 。
常用解决方案有:基于可靠消息(MQ)的解决方案、两阶段事务提交、柔性事务等 。
排序、分页、函数计算问题
在使用 SQL 时 order by,limit 等关键字需要特殊处理,一般来说采用分片的思路:
先在每个分片上执行相应的函数,然后将各个分片的结果集进行汇总和再次计算,最终得到结果 。
分布式 ID
如果使用 Mysql 数据库在单库单表可以使用 id 自增作为主键,分库分表了之后就不行了,会出现id 重复 。
常用的分布式 ID 解决方案有:
  • UUID
  • 基于数据库自动单独维护一张 ID表
  • 号段模式
  • Redis 缓存
  • 雪花算法(Snowflake)
  • 百度uid-generator
  • 美团Leaf
  • 滴滴Tinyid
这些方案后面会写文章专门介绍,这里不再展开 。
多数据源
分库分表之后可能会面临从多个数据库或多个子表中获取数据,一般的解决思路有:客户端适配和代理层适配 。
业界常用的中间件有:
  • shardingsphere(前身 sharding-jdbc)
  • Mycat
总结
如果出现数据库问题不要着急分库分表,先看一下使用常规手段是否能够解决 。
分库分表会给系统带来巨大的复杂性,不是万不得已建议不要提前使用 。作为系统架构师可以让系统灵活性和可扩展性强,但是不要过度设计和超前设计 。在这一点上,架构师一定要有前瞻性,提前做好预判 。大家学会了吗?

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


推荐阅读