Skip to content

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

  • 标签:后端、MySQL、数据库

🏛 业务架构师 ​

分库分表是把数据按规则拆到多个库表的水平/垂直扩展手段:

  • 垂直分库:按业务域拆(订单库、商品库、用户库)——本质是限界上下文的物理化,跟随微服务拆分走;
  • 垂直分表:宽表按冷热拆(订单主表 + 详情扩展表)——高频字段瘦身,提升缓存命中;
  • 水平分表/分库:单表数据按规则横向拆:哈希取模(分布均匀,扩容要迁数据)、范围(按时间/ID 段,天然冷热分离但热点集中)、时间(日志、流水类首选,配合归档)。

架构师视角,关键不是"怎么做"而是"什么时候才做、代价是什么":

引入时机的判断信号:单表行数逼近 2000 万且树高增长、写入 QPS 到单库上限、磁盘与备份时间失控。但触发动作前先走便宜的阶梯:归档冷数据(交易表留 3 个月)→ 读写分离 → 缓存/ES 分流查询 → 最后才分片。

真实代价清单(低估必悔):

  • 分片键决定一切:选 user_id 则"按商家查全量订单"要扫全部分片——分片键必须匹配主流查询主体,这是业务建模决策不是 DBA 决策;
  • 跨片查询、跨片事务、全局唯一 ID、二次扩容(成倍翻分片数)都要专门方案;
  • 生态改造成本:所有 DAL、报表、数据同步链路重做。

我的实践:用 ShardingSphere 等中间件收敛复杂度,先垂直拆库随服务走,水平分片宁晚勿早——它是单向门,迈过去就回不来了,能靠架构调整多扛一年,就把这一年的业务确定性留给决策。

🏗 系统架构师 ​

分库分表是数据层的水平扩展手段,当单表数据量(经验值 2000 万~5000 万行/100GB)或单库写入 TPS 摆脱不了单机瓶颈时启用。

两种基本策略:

  • 垂直拆分:按业务/字段切。垂直分库(订单库、用户库、商品库分离,服务边界对齐,为微服务铺路)、垂直分表(宽表拆冷热列,热点列小表 + 大字段冷表);
  • 水平拆分:按分片键把行打散到多库多表:shard = hash(分片键) % N。

水平分片的路由方案:

  • hash 取模:分布均匀,但扩容要迁移数据(翻倍扩容 + 一致性哈希可缓解);
  • range 按范围(时间、ID 区间):利于范围查询与冷热归档,但写热点集中在新分片——订单按月分表就是典型;
  • 分片键选择是第一决策:必须覆盖 80% 以上查询的维度(订单用 user_id,避免广播全分片查询);非分片键查询靠"基因法"(把 user_id 基因编进订单号)、异构索引表或 ES/宽表兜底。

配套代价(架构师必须讲):跨分片 join/事务(改业务聚合、走最终一致)、分布式 ID(雪花)、扩容数据迁移(双写 + 灰度切换)、ShardingSphere/Vitess 等中间件选型。我的原则:先垂直拆、再读写分离、缓存与归档穷尽之后才水平分,因为它是单向门,做完很难回头。

💻 全栈开发专家 ​

分库分表 = 把单库单表的数据按规则拆到多个库/多个表,应对单表数据量(经验值 2000 万行/2TB)和单实例写入能力到达极限。

类型:

  • 垂直分库:按业务域拆(订单库、商品库、用户库),边界清晰,微服务化的前置动作。
  • 垂直分表:按列拆冷热(高频小字段一张表,大文本 blob 挪出去),解决行太宽、buffer pool 命中率低。
  • 水平分库分表:按行拆——hash 取模(均匀,扩容要迁移数据)、range 按时间(自然归档友好,冷热分离)、基因法/查找表(按用户维度路由)。
sql
-- ShardingSphere-JDBC 配置示意
rules:
  sharding:
    tables:
      t_order:
        actual-data-nodes: ds_${0..1}.t_order_${0..3}
        database-strategy:
          standard:
            sharding-column: user_id
            sharding-algorithm-name: db-mod

必须能答出的连带问题:

  1. 分布式 ID:自增 id 冲突,换雪花/号段;
  2. 跨分片查询/分页/join:路由聚合或冗余宽表 + ES 二级索引;
  3. 分布式事务:同 user 数据落同库尽量避免跨库事务,必要用最终一致;
  4. 扩容:一致性 hash 或双写迁移(老新双写 → 历史迁移 → 校验 → 切读 → 切写)。

我的原则:先索引优化、缓存、归档冷数据,分库分表是最后手段,一旦拆了就回不去了。