数据库分库分表解决大数据量:分库分表解决大数据量问题
什么情况下需要分库分表
当你单表数据超过 500 万甚至上亿时,查询会越来越慢,索引膨胀、磁盘 IO 吃紧。
这时“分库分表”就是一种常见的数据库优化手段。
它的核心思路很简单:把一个大表拆成多个小表(分表),或者把数据分散到不同数据库(分库),减轻单库单表的压力。
经典场景:用户订单表、日志表、消息记录表等持续增长的业务表。
分库分表的核心思路:水平拆分与垂直拆分
- 垂直分库:按业务模块拆,比如订单库、用户库、商品库。
- 水平分表:按某个字段(如用户 ID)取模,将同一张表的数据均匀散到多个结构相同的表里。
- 水平分库:数据分散到多个物理数据库,配合分片键路由。
零基础用户建议先学水平分表,复杂度最低。
本文就用 ShardingSphere-JDBC 演示水平分表操作。
实操:用 ShardingSphere-JDBC 实现水平分表
1. 准备环境
- MySQL 5.7+ 或 8.0,创建数据库
test_db。 - Java 8+,Maven 项目(或 Spring Boot)。
- 引入依赖(以 Maven 为例):
org.apache.shardingsphere
shardingsphere-jdbc-core-spring-boot-starter
5.3.2
2. 数据库初始化
在 MySQL 里创建两张结构完全相同的表:
CREATE TABLE order_0 (
order_id BIGINT PRIMARY KEY,
user_id INT,
amount DECIMAL(10,2)
);
CREATE TABLE order_1 (
order_id BIGINT PRIMARY KEY,
user_id INT,
amount DECIMAL(10,2)
);
3. 配置分片规则(application.yml)
spring:
shardingsphere:
datasource:
names: ds0
ds0:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://localhost:3306/test_db
username: root
password: your_password
rules:
sharding:
tables:
order:
actual-data-nodes: ds0.order_$->{0..1}
table-strategy:
standard:
sharding-column: user_id
sharding-algorithm-name: order-inline
sharding-algorithms:
order-inline:
type: INLINE
props:
algorithm-expression: order_$->{user_id % 2}
说明:user_id % 2表示按用户 ID 的奇偶性路由到order_0或order_1。
4. 写代码插入与查询
@Autowired
private JdbcTemplate jdbcTemplate;
public void insertOrder(Long orderId, Integer userId, BigDecimal amount) {
jdbcTemplate.update("INSERT INTO order (order_id, user_id, amount) VALUES (?,?,?)",
orderId, userId, amount);
}
public List
注意:SQL 里表名写逻辑表 order,ShardingSphere 会自动路由到真实物理表。
分库分表常见坑点
- 分片键选择不当:如果分片键是高频查询字段(如 order_id),但业务按 user_id 查询,就会跨所有表,反而更慢。建议分片键按最常用的查询条件选。
- 跨表分页:
LIMIT 10 OFFSET 20在分表后会变成每张表查 30 条再合,性能差。建议用业务中间表或搜索引擎兜底。 - 分布式事务:分库后跨库事务需要引入 Seata 等方案;分表在同一库下无此问题。本文演示的分表在同一库,不用操心。
- 自增主键冲突:不同分表的主键可能重复。可以改成雪花算法或自定义主键生成器。
验证效果与总结
插入测试数据:模拟 10 个用户,每个用户插入 3 条订单。
-- 查看实际数据分布
SELECT 'order_0' AS tbl, COUNT(*) FROM order_0
UNION ALL
SELECT 'order_1', COUNT(*) FROM order_1;
你会看到数据被均匀拆分。
再跑一次原来的慢查询,性能提升明显。
分库分表不是银弹,但对于单表大数据量场景确实有效。
建议先从小规模分表入手,等业务量真的破千万级别再考虑分库。
按本文步骤走完,你就具备实际落地的能力了。
实际操作中如果遇到配置不生效,优先检查 actual-data-nodes 的表名与实际是否一致。