什么是分库?分表?分库分表?


一则或许对你有用的小广告

欢迎加入小哈的星球,你将获得:专属的实战项目(4个项目都能学) / 1v1 提问 / 简历修改 / Java 学习路线 / 社群讨论 / 学习打卡 / 每月赠书

  • 《Spring AI 项目实战(问答机器人、RAG 智能客服、联网搜索)》已完结,基于 Spring AI + Spring Boot 3.x + JDK 21...查看介绍

  • 《从零手撸:仿小红书(微服务架构)》 已完结,基于 Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...查看介绍;演示链接:http://116.62.199.48:7070/

  • 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接:http://116.62.199.48/

  • 新开坑项目:《从零手撸:秒杀系统高并发优化实战》 正在更新中...,查看介绍

截止目前,星球内专栏累计输出 150w+ 字,讲解图 5110+ 张,还在持续爆肝中.. 后续还会上新更多项目,已有 4700+ 小伙伴加入学习,欢迎点击围观

面试考察点

  1. 概念清晰度:面试官想知道你是不是真懂这三者的区别,而不是把它们当成同一个东西混着讲。很多人一张嘴就把 “分库分表” 说成一个动作,这就露馅了。

  2. 场景判断力:什么时候单库扛得住、什么时候要分表、什么时候必须分库,这种判断能力比会用中间件更值钱。

  3. 架构演进意识:分库分表从来不是上来就干的,而是单库优化、读写分离、缓存这些都做完之后,仍然扛不住才考虑的方案。能不能讲清楚这个演进过程,体现的是真实的架构经验。

核心答案

先把三个概念一刀切清楚:

概念 做的事情 解决的问题 物理层面
分表 把一张大表拆成多张表 单表数据量过大(查询慢、DDL 卡) 同一个数据库实例内
分库 把一个库拆成多个库 单库连接数、QPS、磁盘 IO 扛不住 多个数据库实例
分库分表 既拆库又拆表 数据量大 + 并发高,单库单表双双见顶 多实例 + 多表

一句话总结:分表解决 “数据多”,分库解决 “压力大”,分库分表解决 “又多又压”

深度解析

一、为什么会出现 “数据多” 和 “压力大”

先看一个典型的 MySQL 性能瓶颈演进过程,这块很多文章一笔带过,但实际踩过坑的人都知道:

  • 单表数据量超过 500 万行 / 2GB:阿里《Java 开发手册》官方建议的 “推荐分库分表” 阈值,B+ 树层级开始增加,查询开始变慢
  • 单表数据量超过 2000 万行:这是行业广泛流传的 “性能拐点”,再优化收益也有限
  • 单库 TPS / QPS 上来:连接池打满、锁竞争加剧、磁盘 IO 饱和
  • 单库数据文件过大:备份、恢复、DDL 都变得极慢

单库单表的性能瓶颈
单库单表的性能瓶颈

上面这条演进路线是面试加分项,一定要记住:分库分表是 “前面招都用完了还扛不住” 才上的最后招。我面试时常反问一句 “为什么不用读写分离和索引优化解决?”,能答上来的人不多。

分库分表前的优化路径
分库分表前的优化路径

二、分表的两种姿势:垂直 vs 水平

垂直分表:把一张表的列拆开,按 “热冷字段” 或 “长短字段” 拆分。

比如 user 表有 30 个字段,把常用的 idnameavatar 放主表,把不常用的 bioaddressextend_json 拆到扩展表。好处是热数据行变小,单页能装下更多行,缓冲池命中率提升。

水平分表:把一张表按行拆开,按某个分片键(如 user_id)路由到多张子表。

比如 order_0order_1order_2...order_15,16 张表存同一个逻辑 order 的数据。这是日常说的 “分表” 主流形态。

垂直分表和水平分表
垂直分表和水平分表

上面两组拆法的核心差异:垂直分表减少的是 “列宽”,水平分表减少的是 “行数”。垂直分表治 “字段太杂”,水平分表治 “数据太多”。

垂直分表与水平分表对比
垂直分表与水平分表对比

三、分库的两种姿势:垂直 vs 水平

跟分表一样,分库也分垂直和水平:

  • 垂直分库:按业务边界拆。比如电商系统把 user_dborder_dbproduct_dbpayment_db 各自独立。这是微服务化的前置条件。
  • 水平分库:同一个业务的库,按某个分片键拆成多个结构相同的库。比如 user_db_0user_db_1user_db_2,根据 user_id % 3 路由。

垂直分库和水平分库
垂直分库和水平分库

垂直分库是 “业务问题”,为了解耦和扩展性;水平分库是 “性能问题”,为了分摊单库压力。

垂直分库与水平分库对比
垂直分库与水平分库对比

四、分库分表:终极形态

把水平分库和水平分表叠在一起就是 “分库分表”。比如拆 4 个库,每个库 16 张表,一共 64 张子表:

水平分库分表架构
水平分库分表架构

这种方案能扛住海量数据 + 高并发,但代价也大:跨库 Join、分布式事务、全局唯一 ID、运维复杂度全来了。所以一句话:不到万不得已不要上分库分表,上了就回不去了

分库分表的收益与代价
分库分表的收益与代价

五、Java 生态里的落地工具

工具 类型 特点
ShardingSphere-JDBC Client 端 改造轻量,无中间件,性能好
ShardingSphere-Proxy Proxy 端 对应用透明,运维友好
MyCat Proxy 端 老牌方案,社区活跃度下降
TiDB / OceanBase 分布式数据库 业务无感知,但成本高

Java 项目里最常见的是 ShardingSphere-JDBC,引入一个 Maven 依赖 + 配置分片规则就能用,比迁移到 TiDB 改造成本低得多。

面试高频追问

  1. 追问一:分片键怎么选?

    按高频查询条件选。订单系统按 user_id 分,因为买家视角查询最多。千万不要选 create_timeid 这种容易产生数据倾斜的字段。

  2. 追问二:分库分表后,跨库 Join 怎么办?

    三种思路:业务层多次查询组装、把需要 Join 的表做 “绑定表” 或 “广播表”、把数据同步到 ES 做宽表查询。生产中 ES + 分库分表 的组合特别常见。

  3. 追问三:分库分表后分页查询怎么办?

    全局分页是分库分表的老大难。常见做法:禁止跨页跳转、用游标分页(WHERE id > last_id)、二次查询合并法。这是个深坑,能聊一整面。

  4. 追问四:分布式 ID 用什么?

    雪花算法(Snowflake)、Leaf、TinyID、数据库号段。Snowflake 最经典,但要注意时钟回拨问题。

常见面试变体

  • “什么时候该分库分表?数据量到多少?”
  • “分库分表后怎么做数据迁移?双写方案怎么落地?”
  • “ShardingSphere 的分片策略有哪几种?”
  • “为什么大厂都用 Snowflake,不用数据库自增 ID?”

记忆口诀

分表治 “行多”,分库治 “压大”,分库分表一起上,能扛海量又能扛并发

垂直拆是按业务/字段切,水平拆是按数据行切。记住这条线,三个概念不会混。

总结

分库分表不是银弹,是单库优化、读写分离、缓存都做完后的 “最后一公里”。回答时先把三个概念一刀切清楚(分表解决数据量、分库解决并发压力、分库分表两者皆治),再聊垂直 vs 水平、分片键选择、跨库 Join 这些落地的坑,面试官就知道你是真做过,而不是背的八股。