分库:将表按照某种规则拆分到多个数据库中,来保证系统的稳定和性能
分表:将表中数据按照某种规则拆分到多张表中,提升查询效率
分库分表的原因
- 分库原因:数据量过大,而磁盘空间、内存、CPU 有限
- 分表原因:单表承载能力有限,随着数据规模的增加,表索引效率降低
- 其他原因:分布式或微服务架构,根据业务需求和功能对数据库进行划分
单表超 500 万行,或容量超 2GB 时推荐分库分表——阿里开发手册
分库分表的常见方法
- 垂直分库
将某个库中的表拆分到多个库,一般按照业务维度拆分
优点:降低单数据库服务的压力,增加系统可用性;业务清晰,各系统间解耦合;提升 IO 性能,增加数据库链接数以及其他硬件的瓶颈
缺点:不同库之间的数据一致性无法保证,需要通过分布式事务;依然存在单库、单表数据过大的问题,需要结合水平拆分
- 垂直分表
将存在一张表中的不同字段拆分为多张表;拆分后的表字段、结构均不同
尽量从高频访问的"核心表"中剥离经常修改的、数据较大的、不常查询的字段
优点:降低表的数据规模,提升效率;减少单条数据占用空间,减少磁盘 IO
缺点:依然存在单表数据过大的问题,需要结合水平拆分
- 水平分库
是将数据库中的表数据按照某种规则拆分到多个库中,以实现水平扩展
优点:降低单库数据规模,提高系统高并发能力;业务代码改动小,不需要拆分业务
缺点:跨库的 join 关联查询性能较差,增加开发复杂度;单库的自增 ID 受影响
- 水平分表
将数据按照某种规则拆分到多张表,多张表还在一个库里且结构相同
优点:减少单表数据量,提升查询效率;业务代码改动小,不需要拆分业务
缺点: 多张表属于一个库,数据库的压力仍存在
分库分表的可能隐患:
- 数据不一致,需要分布式事物来保证数据库操作的原子性
- 主键唯一性冲突,需要根据策略生成全局唯一的分布式 ID
- 通过合理分库、字段冗余等方式尽量避免跨库多表 join 的情况
- 跨库聚合查询(比如分组排序)复杂,可借助分布式框架如 ES\