什么是分库?分表?分库分表?
一则或许对你有用的小广告
欢迎加入小哈的星球,你将获得:专属的实战项目(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+ 小伙伴加入学习,欢迎点击围观
面试考察点
-
概念清晰度:面试官想知道你是不是真懂这三者的区别,而不是把它们当成同一个东西混着讲。很多人一张嘴就把 “分库分表” 说成一个动作,这就露馅了。
-
场景判断力:什么时候单库扛得住、什么时候要分表、什么时候必须分库,这种判断能力比会用中间件更值钱。
-
架构演进意识:分库分表从来不是上来就干的,而是单库优化、读写分离、缓存这些都做完之后,仍然扛不住才考虑的方案。能不能讲清楚这个演进过程,体现的是真实的架构经验。
核心答案
先把三个概念一刀切清楚:
| 概念 | 做的事情 | 解决的问题 | 物理层面 |
|---|---|---|---|
| 分表 | 把一张大表拆成多张表 | 单表数据量过大(查询慢、DDL 卡) | 同一个数据库实例内 |
| 分库 | 把一个库拆成多个库 | 单库连接数、QPS、磁盘 IO 扛不住 | 多个数据库实例 |
| 分库分表 | 既拆库又拆表 | 数据量大 + 并发高,单库单表双双见顶 | 多实例 + 多表 |
一句话总结:分表解决 “数据多”,分库解决 “压力大”,分库分表解决 “又多又压”。
深度解析
一、为什么会出现 “数据多” 和 “压力大”
先看一个典型的 MySQL 性能瓶颈演进过程,这块很多文章一笔带过,但实际踩过坑的人都知道:
- 单表数据量超过 500 万行 / 2GB:阿里《Java 开发手册》官方建议的 “推荐分库分表” 阈值,B+ 树层级开始增加,查询开始变慢
- 单表数据量超过 2000 万行:这是行业广泛流传的 “性能拐点”,再优化收益也有限
- 单库 TPS / QPS 上来:连接池打满、锁竞争加剧、磁盘 IO 饱和
- 单库数据文件过大:备份、恢复、DDL 都变得极慢
上面这条演进路线是面试加分项,一定要记住:分库分表是 “前面招都用完了还扛不住” 才上的最后招。我面试时常反问一句 “为什么不用读写分离和索引优化解决?”,能答上来的人不多。
二、分表的两种姿势:垂直 vs 水平
垂直分表:把一张表的列拆开,按 “热冷字段” 或 “长短字段” 拆分。
比如 user 表有 30 个字段,把常用的 id、name、avatar 放主表,把不常用的 bio、address、extend_json 拆到扩展表。好处是热数据行变小,单页能装下更多行,缓冲池命中率提升。
水平分表:把一张表按行拆开,按某个分片键(如 user_id)路由到多张子表。
比如 order_0、order_1、order_2...order_15,16 张表存同一个逻辑 order 的数据。这是日常说的 “分表” 主流形态。
上面两组拆法的核心差异:垂直分表减少的是 “列宽”,水平分表减少的是 “行数”。垂直分表治 “字段太杂”,水平分表治 “数据太多”。
三、分库的两种姿势:垂直 vs 水平
跟分表一样,分库也分垂直和水平:
- 垂直分库:按业务边界拆。比如电商系统把
user_db、order_db、product_db、payment_db各自独立。这是微服务化的前置条件。 - 水平分库:同一个业务的库,按某个分片键拆成多个结构相同的库。比如
user_db_0、user_db_1、user_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 改造成本低得多。
面试高频追问
-
追问一:分片键怎么选?
按高频查询条件选。订单系统按
user_id分,因为买家视角查询最多。千万不要选create_time、id这种容易产生数据倾斜的字段。 -
追问二:分库分表后,跨库 Join 怎么办?
三种思路:业务层多次查询组装、把需要 Join 的表做 “绑定表” 或 “广播表”、把数据同步到 ES 做宽表查询。生产中 ES + 分库分表 的组合特别常见。
-
追问三:分库分表后分页查询怎么办?
全局分页是分库分表的老大难。常见做法:禁止跨页跳转、用游标分页(
WHERE id > last_id)、二次查询合并法。这是个深坑,能聊一整面。 -
追问四:分布式 ID 用什么?
雪花算法(Snowflake)、Leaf、TinyID、数据库号段。Snowflake 最经典,但要注意时钟回拨问题。
常见面试变体
- “什么时候该分库分表?数据量到多少?”
- “分库分表后怎么做数据迁移?双写方案怎么落地?”
- “ShardingSphere 的分片策略有哪几种?”
- “为什么大厂都用 Snowflake,不用数据库自增 ID?”
记忆口诀
分表治 “行多”,分库治 “压大”,分库分表一起上,能扛海量又能扛并发。
垂直拆是按业务/字段切,水平拆是按数据行切。记住这条线,三个概念不会混。
总结
分库分表不是银弹,是单库优化、读写分离、缓存都做完后的 “最后一公里”。回答时先把三个概念一刀切清楚(分表解决数据量、分库解决并发压力、分库分表两者皆治),再聊垂直 vs 水平、分片键选择、跨库 Join 这些落地的坑,面试官就知道你是真做过,而不是背的八股。
