当前位置: 首页 > news >正文

淘客系统数据库分库分表实践:基于用户 ID 与时间维度的 Sharding 策略

淘客系统数据库分库分表实践:基于用户 ID 与时间维度的 Sharding 策略

大家好,我是 微赚淘客系统3.0 的研发者省赚客!

在高并发、大数据量场景下,单库单表早已无法满足淘客系统的业务需求。微赚淘客系统3.0 在日订单量突破千万级后,我们对核心数据表(如订单表、佣金流水表)进行了分库分表改造,采用基于用户 ID 与时间维度的复合 Sharding 策略,有效提升了系统吞吐能力与查询效率。

一、Sharding 策略设计原则

我们的核心目标是:

  • 写入均匀:避免热点写入导致单库负载过高;
  • 查询高效:支持按用户 ID 快速定位分片,同时兼顾时间范围查询;
  • 扩容平滑:未来可线性扩展分库数量而不影响历史数据。

为此,我们选择用户 ID 哈希取模 + 时间范围分表的混合策略。具体如下:

  • 分库依据user_id % db_count,确保同一用户的所有数据落在同一库,便于事务一致性;
  • 分表依据:按月分表,如order_202512order_202601,便于冷热分离与归档。

二、ShardingSphere 配置实现

我们使用 Apache ShardingSphere 5.x 作为中间件,通过 Java 配置方式定义分片规则。以下为关键代码示例:

packagejuwatech.cn.sharding.config;importorg.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;importorg.apache.shardingsphere.api.sharding.standard.PreciseShardingValue;importorg.springframework.stereotype.Component;importjava.util.Collection;importjava.util.stream.Collectors;@ComponentpublicclassUserIdPreciseShardingAlgorithmimplementsPreciseShardingAlgorithm<Long>{privatestaticfinalintDB_COUNT=8;@OverridepublicStringdoSharding(Collection<String>availableTargetNames,PreciseShardingValue<Long>shardingValue){LonguserId=shardingValue.getValue();Stringtarget="ds"+(userId%DB_COUNT);if(availableTargetNames.contains(target)){returntarget;}thrownewIllegalArgumentException("No database found for user_id: "+userId);}}

时间维度分表算法如下:

packagejuwatech.cn.sharding.algorithm;importorg.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;importorg.apache.shardingsphere.api.sharding.standard.PreciseShardingValue;importorg.springframework.stereotype.Component;importjava.time.LocalDateTime;importjava.time.format.DateTimeFormatter;importjava.util.Collection;@ComponentpublicclassOrderTablePreciseShardingAlgorithmimplementsPreciseShardingAlgorithm<LocalDateTime>{privatestaticfinalDateTimeFormatterFORMATTER=DateTimeFormatter.ofPattern("yyyyMM");@OverridepublicStringdoSharding(Collection<String>availableTargetNames,PreciseShardingValue<LocalDateTime>shardingValue){Stringsuffix=shardingValue.getValue().format(FORMATTER);StringtargetTable="t_order_"+suffix;if(availableTargetNames.contains(targetTable)){returntargetTable;}// 若目标表不存在,可动态创建或回退到默认表(生产环境建议预建)return"t_order_default";}}

三、Spring Boot 集成配置

application.yml中配置数据源与分片规则:

spring:shardingsphere:datasource:names:ds0,ds1,ds2,ds3,ds4,ds5,ds6,ds7ds0:type:com.zaxxer.hikari.HikariDataSourcedriver-class-name:com.mysql.cj.jdbc.Driverjdbc-url:jdbc:mysql://db0.juwatech.cn:3306/order_db_0username:rootpassword:***# ... ds1 ~ ds7 类似配置rules:sharding:tables:t_order:actual-data-nodes:ds$->{0..7}.t_order_$->{202501..202612}database-strategy:standard:sharding-column:user_idprecise-algorithm-class-name:juwatetech.cn.sharding.config.UserIdPreciseShardingAlgorithmtable-strategy:standard:sharding-column:create_timeprecise-algorithm-class-name:juwatech.cn.sharding.algorithm.OrderTablePreciseShardingAlgorithm

注意:actual-data-nodes中的时间范围需根据业务预估提前配置,避免运行时找不到表。

四、DAO 层与实体类示例

订单实体类需包含分片键:

packagejuwatech.cn.entity;importjava.time.LocalDateTime;publicclassOrder{privateLongid;privateLonguserId;// 分库键privateLocalDateTimecreateTime;// 分表键privateStringorderNo;privateLongcommission;// getters & setters}

MyBatis Mapper 示例:

packagejuwatech.cn.mapper;importjuwatech.cn.entity.Order;importorg.apache.ibatis.annotations.Insert;importorg.apache.ibatis.annotations.Mapper;importorg.apache.ibatis.annotations.Select;@MapperpublicinterfaceOrderMapper{@Insert("INSERT INTO t_order (user_id, create_time, order_no, commission) "+"VALUES (#{userId}, #{createTime}, #{orderNo}, #{commission})")voidinsert(Orderorder);@Select("SELECT * FROM t_order WHERE user_id = #{userId} AND create_time BETWEEN #{startTime} AND #{endTime}")List<Order>findByUserIdAndTimeRange(@Param("userId")LonguserId,@Param("startTime")LocalDateTimestartTime,@Param("endTime")LocalDateTimeendTime);}

由于 ShardingSphere 能自动路由,上述查询无需手动指定表名,只要传入user_idcreate_time,中间件即可定位到具体库表。

五、注意事项与优化点

  1. 跨分片查询限制:避免SELECT * FROM t_order WHERE commission > 100这类无分片键的查询,会导致全库扫描;
  2. 分页性能:大偏移量分页(如LIMIT 100000, 20)性能差,建议改用游标分页(基于id > lastId);
  3. DDL 同步:新增字段需通过运维脚本同步到所有分库分表;
  4. 时间分表预建:建议通过定时任务每月初自动创建下月表,避免运行时异常。

六、效果验证

上线后,单库 QPS 从 12,000 降至 1,500 以下,慢查询下降 92%,订单写入延迟稳定在 10ms 内。复合 Sharding 策略在保证数据隔离的同时,显著提升了系统可扩展性。

本文著作权归 微赚淘客系统3.0 研发团队,转载请注明出处!

http://www.jsqmd.com/news/321981/

相关文章:

  • 医疗保健GEO优化攻略:杭州专业公司引领行业新风尚,GEO优化AI工具排名/GEO服务,GEO优化老牌厂家推荐
  • 标针冲压工艺及模具设计
  • 1.操作系统介绍
  • 2026年卫星通信实验教学系统选购宝典:优势品牌厂家采购渠道有哪些?
  • 【计算机毕业设计案例】基于SpringBoot的蔬菜种植管理蔬菜种植园管理系统 绿色菜园智能管理平台系统设计与实现(程序+文档+讲解+定制)
  • 便携式智能交通灯控制器的研发
  • 为什么CS2提示“api-ms-win-crt-runtime-l1-1-0.dll缺失”?2026最新解决方案来了
  • 2026年优质灯具品牌推荐:聚焦技术与品质的行业精选
  • 大文件pdf转word,免费压缩转换一步到位
  • 企业网盘选型指南:从核心能力清单到主流产品深度对比
  • 工业超级智能体如何提升制造企业整体协同效率?
  • 手机端pdf转word,免费工具随时随地转
  • 商用自动面条机厂家测评推荐:3家主流品牌PK,元厨凭何领跑?
  • 2026年工商类民办大学口碑排名,武工商能排第几
  • 1000道互联网大厂 Java 面试真题整理
  • 2026年口碑好的国际高中招生排名,上海林国荣学校实力揭秘
  • 全网最全,软件测试-性能测试面试题汇总(附答案)
  • 手动创建Docker版Fastapi CI/CD镜像文件
  • 用户注册流程的深度测试验证指南:面向测试工程师的实践手册
  • 2026年广西营销推广公司推荐:全域智能运营时代的效果保障与选型指南
  • 如何解决React报Uncaught TypeError: Cannot destructure property ‘xxx‘ of undefined问题
  • 网络运维必备:TCP/IP 协议常见问题与网络故障定位方法
  • Java毕设项目推荐-基于SpringBoot的社区生活服务平台设计与实现基于SpringBoot的社区邻里服务平台设计与实现【附源码+文档,调试定制服务】
  • 基于Backtrader的多维度指数期权备兑策略
  • 软件测试面试大全(全800+题)
  • 答辩 PPT 还在熬夜排版?虎贲等考 AI PPT:10 分钟生成 “学术叙事型” 演示,评委眼前一亮
  • 【深度解析】铝型材框架:核心原理、应用场景与实践指南
  • 智慧农业草莓成熟度检测数据集VOC+YOLO格式1627张5类别
  • 2026年1月厦门家装公司排行:省心装修品牌推荐
  • Wheel包:30秒解决30分钟编译地狱