# 什么是分库分表?分库分表有哪些类型(或策略)?

8 min read
Table of Contents

什么是分库分表?分库分表有哪些类型(或策略)?

分库分表面试标准答案

【核心定义】

分库分表是一种数据库水平拆分技术,通过将单一数据库/表的数据分布到多个数据库/表中,以解决单库单表在数据量、并发量、磁盘IO等方面遇到性能瓶颈的问题。

【关键要点】

  1. 分库(Database Sharding)
    将数据按规则分散到多个物理数据库中,每个数据库实例独立运行,主要解决数据库连接数瓶颈和单机硬件资源限制问题。

  2. 分表(Table Sharding)
    将单表数据按规则拆分到多个物理表中(通常在同一数据库内),主要解决单表数据量过大导致的查询性能下降、索引膨胀问题。

  3. 拆分策略类型

    • 垂直拆分:按业务模块/功能拆分(如用户库、订单库)
    • 水平拆分:按数据行拆分(如按用户ID取模分表)
    • 混合拆分:先垂直后水平,实际生产中最常用

【深度推导/细节】

核心矛盾与解决方案拆解

矛盾1:单表数据量过大(>5000万行)

  • 问题:B+树索引深度增加,磁盘IO次数增多,DDL操作锁表时间长
  • 解决方案:水平分表,将单表拆分为多个小表(如order_0 ~ order_7)

矛盾2:数据库连接数瓶颈

  • 问题:单机MySQL最大连接数有限(默认151),高并发时连接耗尽
  • 解决方案:分库部署,每个库独立连接池,总连接数 = 单库连接数 × 库数量

矛盾3:热点数据集中

  • 问题:某些分片负载过高(如按时间分表时,当前月份表压力大)
  • 解决方案:采用复合分片键(如用户ID+月份),或引入一致性哈希算法

扩容机制逻辑拆解

Step 1:预分片设计

  • 初始设计时预留扩展空间(如按64个分片设计,初期只启用16个)

Step 2:数据迁移过程

1. 双写策略:新老分片同时写入
2. 数据同步:将历史数据迁移到新分片
3. 校验数据:确保数据一致性
4. 流量切换:逐步将读请求切换到新分片
5. 停写老分片:确认无误后停止向老分片写入

Step 3:路由规则更新

  • 动态配置中心更新分片规则
  • 应用重启或热加载新配置

【关联/对比】

维度分库分表适用场景
拆分粒度数据库级别表级别分库解决连接瓶颈,分表解决数据量瓶颈
事务支持分布式事务复杂本地事务可用分表更容易保持事务一致性
跨库查询需要中间件聚合相对简单分表对应用透明性更好
扩容成本较高(涉及数据迁移)较低(可局部扩容)分表扩容更灵活

与读写分离对比:

  • 读写分离:解决读多写少场景,通过主从复制分摊读压力
  • 分库分表:解决数据量大/写并发高场景,本质是数据分布问题

与NoSQL对比:

  • NoSQL(如MongoDB)天生支持分片,但事务能力弱
  • 分库分表是在关系型数据库上实现类似能力,保持ACID特性

『面试官追问』

  1. 如何选择分片键?

    • 选择基数大、分布均匀的字段(如用户ID)
    • 避免选择单调递增字段(如自增ID)导致热点
    • 常用方案:业务主键取模、一致性哈希、范围分片
  2. 分库分表后如何实现全局唯一ID?

    • 雪花算法(Snowflake):64位,包含时间戳+机器ID+序列号
    • 数据库号段模式:批量获取ID段,内存分配
    • UUID:但索引效率低,不适合做InnoDB主键
  3. 跨分片查询如何优化?

    • 禁止多表JOIN跨分片查询
    • 采用冗余字段或宽表设计
    • 复杂查询走Elasticsearch等搜索引擎
    • 分页查询需在各分片查询后内存聚合
  4. 分库分表后事务如何处理?

    • 尽量设计为单库事务
    • 使用Seata等分布式事务框架(2PC/XA)
    • 最终一致性方案(消息队列+本地事务表)
  5. 实际生产中的拆分时机?

    • 单表数据量:>5000万行或>50GB
    • 并发连接数:持续>最大连接数80%
    • 查询响应时间:核心业务>500ms且优化无效
    • 建议:提前规划,避免被动拆分

【直击痛点:关键数字与设计合理性】

  • 5000万行阈值:InnoDB B+树3层高度可存储约5000万行(按16KB页大小,主键8B计算),超过后树变4层,IO次数增加
  • 64个分片上限:过多分片导致连接池膨胀、维护复杂,通常建议2的n次方(16/32/64)便于取模运算
  • 双写过渡期:通常设置1-2周,确保数据完全同步
  • 分片键选择:80%查询应能通过分片键直接定位,避免广播查询

【版本差异与实践演进】

  • 早期方案:应用层硬编码分片逻辑(2015年前)
  • 中间件时代:MyCAT、ShardingSphere(2015-2020)
  • 云原生时代:Vitess(K8s)、PolarDB分布式版(2020至今)
  • 趋势:从应用层拆分 → 中间件代理 → 数据库原生支持

最佳实践总结:分库分表是“不得已而为之”的优化手段,应优先考虑读写分离、索引优化、归档历史数据等方案。当必须拆分时,建议采用“垂直拆分优先,水平拆分谨慎”的原则,并选择成熟的中间件(如ShardingSphere)降低开发复杂度。

My avatar

文章看完了,不打算去别的篇章转转吗?👀 感谢你的耐心阅读!如果你有问题想探讨,或者发现了文中的 Bug,请务必通过页脚的链接联系我


More Posts

# 什么是服务雪崩?

7 min read

服务雪崩是指分布式系统中,由于某个基础服务发生故障或性能瓶颈,引发调用链上的一系列服务级联失效,最终导致整个系统不可用的现象。

Read

Comments