1. SpringBoot整合ShardingSphere-JDBC 4.0.0按月分表实战最近在做一个订单管理系统时遇到了单表数据量过大的问题经过技术选型最终决定采用ShardingSphere-JDBC 4.0.0实现按月分表。这里分享下完整的整合过程和踩坑经验。按月分表是解决单表数据膨胀的经典方案特别适合订单、日志等随时间线性增长的业务场景。ShardingSphere作为Apache顶级项目其JDBC模块可以无缝集成到SpringBoot中通过配置即可实现分库分表对业务代码零侵入。2. 核心设计与技术选型2.1 为什么选择按月分表我们的订单表每月新增约300万条数据单表超过2000万后查询性能明显下降。经过测试发现按ID哈希分片会导致范围查询需要扫描所有分片按年分片粒度太粗单个分片仍然过大按月分片既能控制单表数据量(300万/月)又保持了时间维度的查询效率2.2 ShardingSphere-JDBC版本选择选择4.0.0版本主要考虑兼容SpringBoot 2.x生态支持更灵活的分片策略配置提供完善的分布式事务支持社区活跃文档齐全注意4.x版本配置与5.x有较大差异网上很多教程是基于5.x的需要注意区分3. 完整整合步骤3.1 环境准备!-- pom.xml依赖 -- dependency groupIdorg.apache.shardingsphere/groupId artifactIdsharding-jdbc-spring-boot-starter/artifactId version4.0.0/version /dependency dependency groupIdcom.zaxxer/groupId artifactIdHikariCP/artifactId version3.4.5/version /dependency3.2 分表配置详解# application-sharding.yml spring: shardingsphere: datasource: names: ds0 ds0: type: com.zaxxer.hikari.HikariDataSource driver-class-name: com.mysql.jdbc.Driver jdbc-url: jdbc:mysql://localhost:3306/order_db username: root password: 123456 sharding: tables: t_order: actual-data-nodes: ds0.t_order_$-{2020..2030}0$-{1..9},ds0.t_order_$-{2020..2030}1$-{0..2} table-strategy: standard: precise-algorithm-class-name: com.example.config.MonthShardingAlgorithm range-algorithm-class-name: com.example.config.MonthRangeShardingAlgorithm sharding-column: create_time3.3 分片算法实现public class MonthShardingAlgorithm implements PreciseShardingAlgorithmDate { Override public String doSharding(CollectionString availableTargetNames, PreciseShardingValueDate shardingValue) { // 格式: t_order_yyyyMM SimpleDateFormat sdf new SimpleDateFormat(yyyyMM); return t_order_ sdf.format(shardingValue.getValue()); } } public class MonthRangeShardingAlgorithm implements RangeShardingAlgorithmDate { Override public CollectionString doSharding(CollectionString availableTargetNames, RangeShardingValueDate shardingValue) { // 处理BETWEEN AND查询 SetString result new LinkedHashSet(); DateRange range new DateRange(shardingValue.getValueRange()); for (Date date range.lowerEndpoint(); date.before(range.upperEndpoint()); date DateUtils.addMonths(date, 1)) { result.add(t_order_ new SimpleDateFormat(yyyyMM).format(date)); } return result; } }4. 关键问题与解决方案4.1 分布式ID生成分表后自增ID会导致重复我们采用Snowflake算法Bean public KeyGenerator keyGenerator() { return new SnowflakeKeyGenerator(); }4.2 跨月查询优化对于跨多个月份的查询我们做了以下优化在查询条件中尽量带上时间范围对分页查询使用归并排序建立月份维度的联合索引4.3 历史数据迁移已有数据需要按月份迁移到对应分表-- 按月导出数据 SELECT * INTO OUTFILE /tmp/order_202001.csv FROM t_order WHERE create_time BETWEEN 2020-01-01 AND 2020-01-31; -- 导入到分表 LOAD DATA INFILE /tmp/order_202001.csv INTO TABLE t_order_202001;5. 性能测试对比测试环境8核16GMySQL 5.7场景单表(2000万)按月分表(300万/表)单条查询120ms15ms月统计报表2.3s0.4s跨3个月查询3.1s0.7s写入性能800TPS1500TPS6. 生产环境注意事项分表键选择create_time字段必须包含在WHERE条件中否则会全表路由索引设计每个分表需要单独建立索引不能依赖全局索引事务处理跨分片事务需要使用XA或SAGA模式监控配置spring: shardingsphere: metrics: enabled: true name: sharding_statsSQL限制避免使用子查询、UNION等复杂操作经过三个月的生产验证这套方案成功将订单查询性能提升了5-8倍写入吞吐量提升近2倍。最大的收获是分表不是银弹必须配合合理的查询方式和索引设计才能发挥最大效益。
SpringBoot整合ShardingSphere-JDBC实现按月分表实战
发布时间:2026/7/3 1:51:16
1. SpringBoot整合ShardingSphere-JDBC 4.0.0按月分表实战最近在做一个订单管理系统时遇到了单表数据量过大的问题经过技术选型最终决定采用ShardingSphere-JDBC 4.0.0实现按月分表。这里分享下完整的整合过程和踩坑经验。按月分表是解决单表数据膨胀的经典方案特别适合订单、日志等随时间线性增长的业务场景。ShardingSphere作为Apache顶级项目其JDBC模块可以无缝集成到SpringBoot中通过配置即可实现分库分表对业务代码零侵入。2. 核心设计与技术选型2.1 为什么选择按月分表我们的订单表每月新增约300万条数据单表超过2000万后查询性能明显下降。经过测试发现按ID哈希分片会导致范围查询需要扫描所有分片按年分片粒度太粗单个分片仍然过大按月分片既能控制单表数据量(300万/月)又保持了时间维度的查询效率2.2 ShardingSphere-JDBC版本选择选择4.0.0版本主要考虑兼容SpringBoot 2.x生态支持更灵活的分片策略配置提供完善的分布式事务支持社区活跃文档齐全注意4.x版本配置与5.x有较大差异网上很多教程是基于5.x的需要注意区分3. 完整整合步骤3.1 环境准备!-- pom.xml依赖 -- dependency groupIdorg.apache.shardingsphere/groupId artifactIdsharding-jdbc-spring-boot-starter/artifactId version4.0.0/version /dependency dependency groupIdcom.zaxxer/groupId artifactIdHikariCP/artifactId version3.4.5/version /dependency3.2 分表配置详解# application-sharding.yml spring: shardingsphere: datasource: names: ds0 ds0: type: com.zaxxer.hikari.HikariDataSource driver-class-name: com.mysql.jdbc.Driver jdbc-url: jdbc:mysql://localhost:3306/order_db username: root password: 123456 sharding: tables: t_order: actual-data-nodes: ds0.t_order_$-{2020..2030}0$-{1..9},ds0.t_order_$-{2020..2030}1$-{0..2} table-strategy: standard: precise-algorithm-class-name: com.example.config.MonthShardingAlgorithm range-algorithm-class-name: com.example.config.MonthRangeShardingAlgorithm sharding-column: create_time3.3 分片算法实现public class MonthShardingAlgorithm implements PreciseShardingAlgorithmDate { Override public String doSharding(CollectionString availableTargetNames, PreciseShardingValueDate shardingValue) { // 格式: t_order_yyyyMM SimpleDateFormat sdf new SimpleDateFormat(yyyyMM); return t_order_ sdf.format(shardingValue.getValue()); } } public class MonthRangeShardingAlgorithm implements RangeShardingAlgorithmDate { Override public CollectionString doSharding(CollectionString availableTargetNames, RangeShardingValueDate shardingValue) { // 处理BETWEEN AND查询 SetString result new LinkedHashSet(); DateRange range new DateRange(shardingValue.getValueRange()); for (Date date range.lowerEndpoint(); date.before(range.upperEndpoint()); date DateUtils.addMonths(date, 1)) { result.add(t_order_ new SimpleDateFormat(yyyyMM).format(date)); } return result; } }4. 关键问题与解决方案4.1 分布式ID生成分表后自增ID会导致重复我们采用Snowflake算法Bean public KeyGenerator keyGenerator() { return new SnowflakeKeyGenerator(); }4.2 跨月查询优化对于跨多个月份的查询我们做了以下优化在查询条件中尽量带上时间范围对分页查询使用归并排序建立月份维度的联合索引4.3 历史数据迁移已有数据需要按月份迁移到对应分表-- 按月导出数据 SELECT * INTO OUTFILE /tmp/order_202001.csv FROM t_order WHERE create_time BETWEEN 2020-01-01 AND 2020-01-31; -- 导入到分表 LOAD DATA INFILE /tmp/order_202001.csv INTO TABLE t_order_202001;5. 性能测试对比测试环境8核16GMySQL 5.7场景单表(2000万)按月分表(300万/表)单条查询120ms15ms月统计报表2.3s0.4s跨3个月查询3.1s0.7s写入性能800TPS1500TPS6. 生产环境注意事项分表键选择create_time字段必须包含在WHERE条件中否则会全表路由索引设计每个分表需要单独建立索引不能依赖全局索引事务处理跨分片事务需要使用XA或SAGA模式监控配置spring: shardingsphere: metrics: enabled: true name: sharding_statsSQL限制避免使用子查询、UNION等复杂操作经过三个月的生产验证这套方案成功将订单查询性能提升了5-8倍写入吞吐量提升近2倍。最大的收获是分表不是银弹必须配合合理的查询方式和索引设计才能发挥最大效益。