垂直拆分
- 有多个业务,每个业务单独分到一个实例里面。
- 在一个库中存在过多的表,把这些表拆分到多个库中。
- 把字段过多的表拆分成多个表,每张表包含一部分字段。
水平拆分
把同一张表分为多张表结构相同的表,每张表里存储一部分数据。
拆分的算法也比较多,常见的就是取模、范围、和全局表等。
场景
1、数据量过大,影响了运维操作:备份、大表 DDL 导致主从长时间延迟
2、不同库表之间性能相互影响
分表方案
单表数据量增长速度过快,影响了业务接口的响应时间,但是 MySQL 实例的CPU负载并不高,这时候只需要分表,不需要分库。
表太大,要么是平均行长度太大,要么是表的记录数太多。这就产生两种不同的分表方案,即切分字段(垂直分表)和切分记录(水平分表) 。
垂直分表
按照字段进行拆分,这里面需要考虑一个问题,如何拆分字段才能表上的DML性能最大化,常规的方案是冷热分离。
如果用了数据库中间件就会自动实现查询重写,例如 mycat,sharding-sphere,不用中间件的话,稍微比较麻烦点,可以搞一个 route 表(主键ID, 原表名,字段名,子表名),每次解析SQL时都需要根据原表名 + 字段名去获取需要的子表,然后再改写 SQL,执行 SQL 返回结果,这种代码改造量太大,而且容易出错,故这种垂直拆分在实际业务中用的不多。
优点
◆ 数据库的拆分简单明了;
◆ 数据维护简单;
缺点
◆ 部分表关联无法在数据库级别完成,需要在程序中完成;
◆ 对于访问极其频繁且数据量超大的表仍然存在性能瓶颈,不一定能满足要求;
◆ 事务处理相对更为复杂;
水平分表
水平拆分表就是按照表中的记录进行分片,单表不建议超过 500w。
优点:
◆不会存在某些超大型数据量和高负载的表遇到瓶颈的问题;
◆应用程序端整体架构改动相对较少;
缺点:
◆切分规则相对更为复杂,很难抽象出一个能够满足整个数据库的切分规则;
◆后期数据的维护难度有所增加,人为手工定位数据更困难;
◆应用系统各模块耦合度较高,可能会对后面数据的迁移拆分造成一定的困难。
共同缺点
引入分布式事务的问题。
跨节点Join 的问题。
3. 跨节点合并排序分页问题。
MySQL分区表
MySQL内部分表的解决方案。
好处就是 MySQL 内部实现 SQL 路由的功能,不用去改造业务代码。
分库方案
随着业务的增长,数据量的增加,很多接口响应时间变得很长,经常出现 Timeout,而且通过升级 MySQL 实例配置已经无法解决问题了,这时候就要分库,通常有两种做法:按业务拆库和按表分库。
按业务分库
考虑拆分业务,将库存,价格相关的接口独立出来。
按表分库
将订单表 orders 拆分20个子表。查询的时候要先通过分区键 user_id 定位是哪个 RDS 实例,再定位到具体的子表,然后做 DML操作。
问题是代码改造的工作量大,而且服务调用链路变长了,对系统的稳定性有一定的影响。
参考
https://blog.csdn.net/agonie201218/article/details/110823552