在实际的 Java 后端开发中,MySQL 单库单表几乎是所有系统的起点,但绝不会是终点。
当数据量和并发量不断增长时,分库分表几乎是绕不开的话题。

本文将从工程实践的角度,系统讲解:
-
什么是垂直分表、垂直分库
-
什么是水平分表、水平分库
-
各自的适用场景、优缺点
-
Java 后端常见落地方式
一、为什么需要分库分表?
在系统早期,常见架构如下:
应用 → MySQL(单库单表)
但随着业务发展,会逐渐出现以下问题:
-
单表数据量过大(百万 / 千万 / 上亿)
-
查询变慢,索引失效严重
-
高并发下锁竞争激烈
-
数据库 CPU、IO 成为瓶颈
-
单机数据库无法继续纵向扩展
分库分表的本质目的只有一个:
提升系统的性能、并发能力和可扩展性
二、先整体认识:垂直拆分 vs 水平拆分
很多初学者容易混淆概念,我们先给出一个整体对比:
| 维度 | 垂直拆分 | 水平拆分 |
|---|---|---|
| 拆分方向 | 按字段拆 | 按数据行拆 |
| 是否减少字段 | ✅ | ❌ |
| 是否减少单表数据量 | ❌ | ✅ |
| 关注点 | 业务 & 字段 | 数据量 & 并发 |
| 实现难度 | 较低 | 较高 |
三、垂直分表(Vertical Table Split)
1. 什么是垂直分表?
把一张字段很多的表,按字段拆成多张表。
拆分前
user(
id,
username,
password,
phone,
email,
avatar,
address,
id_card,
create_time,
update_time
)
这张表存在的问题:
-
字段过多
-
部分字段访问频率极低
-
查询用户列表时加载了大量无用字段
拆分后
user_base(
id,
username,
password,
phone,
email
)
user_profile(
user_id,
avatar,
address,
id_card
)
核心思想:高频字段与低频字段分离
2. 适用场景
-
单表字段数量过多(20+)
-
存在 TEXT / BLOB 等大字段
-
业务查询只关心部分字段
3. 优缺点分析
优点:
-
减少 IO
-
索引更小、查询更快
-
更符合单一职责原则
缺点:
-
需要 JOIN
-
代码复杂度上升
-
不适合强一致性频繁更新
四、垂直分库(Vertical Database Split)
1. 什么是垂直分库?
按照业务模块,把不同表拆分到不同数据库中。
拆分前
db_all:
user
order
product
payment
log
拆分后
db_user:
user
user_profile
db_order:
order
order_item
db_product:
product
inventory
2. 适用场景
-
业务模块清晰
-
不同模块访问压力差异明显
-
微服务架构
3. Java 后端常见实践
-
一个服务对应一个数据库
-
Spring Boot 多数据源
-
每个库独立扩容、独立维护
4. 优缺点分析
优点:
-
业务解耦
-
压力隔离
-
架构清晰
-
易于微服务化
缺点:
-
跨库 JOIN 不支持
-
分布式事务复杂
-
数据一致性依赖业务控制
五、水平分表(Horizontal Table Split)
1. 什么是水平分表?
把一张表的数据,按行拆分到多张结构完全相同的表中。
示例:订单表
order_0
order_1
order_2
...
order_15
每张表只存部分订单数据。
2. 常见拆分方式
① Hash 取模(最常用)
order_id % 16 → order_x
int tableIndex = orderId % 16;
String tableName = "order_" + tableIndex;
② 按时间拆分
order_202601
order_202602
适合订单、日志类数据。
3. 优缺点分析
优点:
-
单表数据量大幅减少
-
索引性能显著提升
-
并发能力增强
缺点:
-
跨表查询困难
-
count(*)、order by复杂 -
扩容需要重新分片
六、水平分库(Horizontal Database Split)
1. 什么是水平分库?
将数据按行分散到多个数据库实例中。
db_0 → order_0 ~ order_15
db_1 → order_16 ~ order_31
2. 典型架构
应用
↓
分片路由层(ShardingSphere)
↓
db_0 / db_1 / db_2
3. 优缺点分析
优点:
-
真正的横向扩展
-
解决单机性能瓶颈
-
支撑超高并发系统
缺点:
-
架构复杂
-
运维成本高
-
分布式事务问题突出
-
跨库查询性能差
七、四种拆分方式总结对比
| 类型 | 拆分对象 | 主要解决问题 |
|---|---|---|
| 垂直分表 | 字段 | 字段过多 |
| 垂直分库 | 业务 | 业务耦合 |
| 水平分表 | 行 | 单表数据量 |
| 水平分库 | 行 + 库 | 单机瓶颈 |
八、真实项目中的推荐拆分顺序
不要一开始就水平分库分表
推荐实践顺序:
-
垂直分表
-
垂直分库
-
水平分表
-
水平分库
九、Java 后端常用中间件
-
ShardingSphere:主流分库分表方案
-
MyBatis / JPA:ORM 层适配
-
Redis:缓存热点数据
-
Seata:分布式事务
十、总结
垂直拆分解决业务和字段复杂度,
水平拆分解决数据量和并发问题。
分库分表不是多此一举,而是一种在系统发展到一定阶段后的必然选择。