面试知识库
困难

分库分表方案#

一句话答案#

数据量大时水平拆分(按行 hash 分到多库多表),中间件选 ShardingSphere,核心问题:跨库 JOIN/分布式事务/全局排序。

核心要点

拆分策略:

策略说明
水平分表按行拆分到多张表(如按user_id hash)
水平分库拆分到多个库实例
垂直分表大字段拆到副表
垂直分库按业务拆库(订单库/用户库)

问题: 跨库JOIN / 分布式事务 / 全局排序分页 / 数据迁移

面试回答(2分钟版)

分库分表是应对数据量和并发量超出单机能力时的水平扩展方案。拆分方式分两类:垂直拆分按业务维度把不同表拆到不同库,比如用户库、订单库;水平拆分是把同一张表的数据按某个分片键 hash 分散到多个库和表中。水平分片的中间件我比较熟悉 ShardingSphere,它在应用层做 SQL 路由和结果归并。分库分表后面临几个核心难题:跨库 JOIN 无法直接执行,通常要通过冗余字段、应用层聚合或宽表来解决;全局排序分页要从每个分片取数据再归并,深分页性能很差;分布式事务需要引入 Seata 或 TCC 等方案;还有全局唯一 ID 要用雪花算法或号段模式。我的建议是单表数据没到千万级、查询没有明显瓶颈就不要分,先考虑读写分离和索引优化。

追问与易错

追问方向:

  • “分库后跨库 JOIN 怎么办?”→ 常用方案:字段冗余避免 JOIN、应用层分别查询再内存聚合、通过 ES/宽表做异构索引、使用中间件如 ShardingSphere 的联邦查询(性能较差慎用)
  • “全局排序分页怎么实现?”→ 每个分片取 offset+size 行数据,归并排序后取目标页;深分页性能极差,建议改为游标分页(WHERE id > last_id)或限制最大翻页深度
  • “分库分表后能回退吗?”→ 理论可以但代价大;通常通过双写迁移方案:先双写新旧库、校验数据一致后切读到新库、最后停旧库写入;回退时反向操作,需提前设计好回退方案

易错点:

  • ❌ 单表几百万就要分——取决于查询和性能
  • ❌ 一开始就分库分表——过早优化