ShardingSphere 分库分表技术详解与 Spring Boot 实践
文章目录前言理论基础1. 分库分表概念2. ShardingSphere 架构组成3. 核心组件4. 原理分析Spring Boot 集成方案1. Maven 依赖配置2. 配置文件设置3. 测试用例4. 测试效果实际应用场景1. 电商订单系统2. 日志分表策略性能优化建议1. 连接池配置2. 查询优化总结前言随着业务规模的增长单一数据库往往无法满足高性能、高并发的需求。ShardingSphere 作为 Apache 基金会顶级项目提供了完整的分布式数据库解决方案其中分库分表功能是最核心的能力之一。本文将深入探讨 ShardingSphere 的分库分表原理并提供 Spring Boot 集成实践方案。理论基础1. 分库分表概念垂直分库按照业务模块将数据分散到不同的数据库实例水平分表将单表数据按照某种规则分散到多个物理表中2. ShardingSphere 架构组成Sharding-JDBC轻量级 Java 框架以 jar 包形式提供服务Sharding-Proxy数据库代理提供透明化的数据库访问Sharding-Sidecar云原生数据库代理开发中3. 核心组件// 数据源配置 DataSource dataSource new ShardingSphereDataSource(); // 分片规则配置 ShardingRuleConfiguration shardingRuleConfig new ShardingRuleConfiguration(); // 分片策略 StandardShardingStrategyConfiguration strategyConfig new StandardShardingStrategyConfiguration();4. 原理分析SQL 解析Sharding-JDBC 会对传入的 SQL 语句进行解析识别出其中的分片键Sharding Key以及相关的表名、字段等信息。这是实现分片路由的基础。public SQLStatement parse(String sql, boolean useCache);分片路由根据解析出的分片键和配置的分片规则Sharding-JDBC 会计算出 SQL 应该路由到哪些实际的数据源和表。这个过程涉及到分片算法的应用比如取模、范围分片等。public RouteContext route(SQLStatement sqlStatement, ShardingRule shardingRule);SQL 改写在确定了目标数据源和表之后Sharding-JDBC 会将原始 SQL 改写为目标数据库可以执行的 SQL。例如将逻辑表名替换为实际的物理表名。public SQLRewriteResult rewrite(RouteContext routeContext);结果归并当查询涉及多个数据源或表时Sharding-JDBC 会将各个数据源返回的结果进行归并最终返回给应用层一个统一的结果集。public MergedResult merge(ListQueryResult queryResults, SQLStatement sqlStatement);事务管理Sharding-JDBC 还支持分布式事务管理确保在多个数据源之间的操作具有一致性。public void begin(); public void commit(); public void rollback();Spring Boot 集成方案1. Maven 依赖配置dependency groupIdorg.apache.shardingsphere/groupId artifactIdshardingsphere-jdbc-core-spring-boot-starter/artifactId version5.2.1/version exclusions exclusion groupIdorg.yaml/groupId artifactIdsnakeyaml/artifactId /exclusion /exclusions /dependency dependency groupIdorg.yaml/groupId artifactIdsnakeyaml/artifactId !-- springboot 2.x 使用 ShardingSphere 推荐的版本 -- version1.33/version /dependency2. 配置文件设置spring: shardingsphere: datasource: names: ds0,ds1 ds0: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/cce-demo username: root password: 12345678 type: com.zaxxer.hikari.HikariDataSource ds1: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/cce-demo-temp username: root password: 12345678 type: com.zaxxer.hikari.HikariDataSource rules: sharding: tables: mp_user: actual-data-nodes: ds${0..1}.mp_user_${0..3} table-strategy: standard: sharding-column: user_id sharding-algorithm-name: mp-user-inline database-strategy: standard: sharding-column: user_id sharding-algorithm-name: database-inline sharding-algorithms: mp-user-inline: type: INLINE props: algorithm-expression: mp_user_${user_id % 4} database-inline: type: INLINE props: algorithm-expression: ds${user_id % 2}3. 测试用例/** * MpUserTest * 所有操作都必须包含分表键不然无法路由 * author senfel * version 1.0 * date 2026/1/30 11:42 */ SpringBootTest TestMethodOrder(MethodOrderer.OrderAnnotation.class) public class MpUserTest { Resource private MpUserMapper mpUserMapper; private static final String testOpenId test_openid_ System.currentTimeMillis(); private static final Long testUserIdNumber generateNumericUserId(); /** * 生成数字格式的用户ID * author senfel * date 2026/1/30 16:59 * return java.lang.Long */ private static Long generateNumericUserId() { // 使用时间戳和随机数生成数字ID long timestamp System.currentTimeMillis(); long random (long) (Math.random() * 1000000L); return timestamp random; } /** * test * author senfel * date 2026/1/30 16:59 * return void */ Test Order(1) public void test() { //插入 MpUser user MpUser.builder() .openid(testOpenId) .deleted(false) .userId(testUserIdNumber) .build(); int result mpUserMapper.insert(user); System.err.println(userId: user.getUserId()); assertTrue(result 0, 插入用户应该成功); //查询 LambdaQueryWrapperMpUser queryWrapper new LambdaQueryWrapper(); queryWrapper.eq(MpUser::getUserId, user.getUserId()); ListMpUser userList mpUserMapper.selectList(queryWrapper); assertNotNull(userList, 根据userId查询结果不应该为null); //修改 LambdaUpdateWrapperMpUser updateWrapper new LambdaUpdateWrapper(); updateWrapper.eq(MpUser::getUserId, user.getUserId()) .set(MpUser::getUserId, testUserIdNumber); result mpUserMapper.update(null, updateWrapper); assertTrue(result 0, 根据userId更新用户应该成功); //删除 result mpUserMapper.delete(updateWrapper); assertTrue(result 0, 根据userId删除用户应该成功); } }4. 测试效果userId: 1769764291467 Creating a new SqlSession SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession2d91f007] was not registered for synchronization because synchronization is not active JDBC Connection [org.apache.shardingsphere.driver.jdbc.core.connection.ShardingSphereConnection3dd09249] will not be managed by Spring Preparing: SELECT id,openid,deleted,user_id FROM mp_user WHERE (user_id ?) Parameters: 1769764291467(Long) Columns: id, openid, deleted, user_id Row: 8388609, test_openid_1769763436874, 0, 1769764291467 Total: 1 Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession2d91f007] Creating a new SqlSession SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession12888eb5] was not registered for synchronization because synchronization is not active JDBC Connection [org.apache.shardingsphere.driver.jdbc.core.connection.ShardingSphereConnection205339e0] will not be managed by Spring Preparing: UPDATE mp_user SET user_id? WHERE (user_id ?) Parameters: 1769764291467(Long), 1769764291467(Long) Updates: 1 Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession12888eb5] Creating a new SqlSession SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession76f3f810] was not registered for synchronization because synchronization is not active JDBC Connection [org.apache.shardingsphere.driver.jdbc.core.connection.ShardingSphereConnection7d7efdf5] will not be managed by Spring Preparing: DELETE FROM mp_user WHERE (user_id ?) Parameters: 1769764291467(Long) Updates: 1 Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession76f3f810]实际应用场景1. 电商订单系统Entity Table(name order) public class Order { Id private Long orderId; private Long userId; private BigDecimal amount; private LocalDateTime createTime; // getter/setter... } // 查询示例 Repository public interface OrderRepository extends JpaRepositoryOrder, Long { ListOrder findByUserId(Long userId); Query(SELECT o FROM Order o WHERE o.userId :userId AND o.createTime BETWEEN :startTime AND :endTime) ListOrder findOrdersByUserIdAndTimeRange(Param(userId) Long userId, Param(startTime) LocalDateTime startTime, Param(endTime) LocalDateTime endTime); }2. 日志分表策略# 按月份分表配置 spring: shardingsphere: rules: sharding: tables: system_log: actual-data-nodes: ds0.system_log_${202301..202312} table-strategy: standard: sharding-column: create_time sharding-algorithm-name: log-month-sharding性能优化建议1. 连接池配置spring: shardingsphere: props: sql-show: true max-connections-size-per-query: 10 acceptor-size: 162. 查询优化合理设计分片键避免跨分片查询使用绑定表减少笛卡尔积合理设置分片数量避免过多分片影响性能总结ShardingSphere 提供了完善的分库分表解决方案通过合理的配置和使用可以有效解决单体数据库的性能瓶颈问题。在实际应用中需要注意1.分片键选择选择合适的分片键是成功的关键2.数据迁移制定完善的数据迁移方案3.监控告警建立完善的监控体系4.版本升级关注新版本特性及时升级通过本文的介绍和实践方案我们可以快速掌握 ShardingSphere 的核心功能并在 Spring Boot 项目中成功集成分库分表能力。

相关新闻

轻松搞定trader-x合约量化策略的实现与优化

轻松搞定trader-x合约量化策略的实现与优化

我做量化交易已经有一段时间了,经历过不少起起伏伏的过程,像很多人一样,也曾在各种平台上尝试过不同的策略和工具。XTrader是我这几年使用最多的一个平台,它的稳定性和功能还是让我挺满意的,尤其是在执行trader-x合约量…

2026/7/5 22:55:19 阅读更多 →
js打开新页签

js打开新页签

// 打开新页签window.open(key, _blank)

2026/7/6 20:21:34 阅读更多 →
制造国企劳动力管理如何突破合规管理困境?

制造国企劳动力管理如何突破合规管理困境?

生产线上的订单波动与上级下达的刚性指标之间,一场关于效率与合规的数字化变革正在悄然进行。“人员总量、人工成本、工资总额”这三条红线,对于制造业国企的HR和信息化负责人而言,既是必须严守的合规底线,也常常被视为业务灵活性…

2026/7/6 15:45:30 阅读更多 →

最新新闻

Balena Etcher终极指南:三步搞定系统启动盘的免费神器

Balena Etcher终极指南:三步搞定系统启动盘的免费神器

Balena Etcher终极指南:三步搞定系统启动盘的免费神器 【免费下载链接】etcher Flash OS images to SD cards & USB drives, safely and easily. 项目地址: https://gitcode.com/GitHub_Trending/et/etcher 还在为制作系统启动盘而烦恼吗?命令…

2026/7/6 22:59:58 阅读更多 →
5分钟高效找回QQ空间青春记忆:GetQzonehistory智能数据恢复指南

5分钟高效找回QQ空间青春记忆:GetQzonehistory智能数据恢复指南

5分钟高效找回QQ空间青春记忆:GetQzonehistory智能数据恢复指南 【免费下载链接】GetQzonehistory 获取QQ空间发布的历史说说 项目地址: https://gitcode.com/GitHub_Trending/ge/GetQzonehistory 还在为QQ空间里那些消失的青春记忆而烦恼吗?那些…

2026/7/6 22:57:55 阅读更多 →
终极指南:如何在Switch和WiiU之间自由转换塞尔达传说旷野之息存档

终极指南:如何在Switch和WiiU之间自由转换塞尔达传说旷野之息存档

终极指南:如何在Switch和WiiU之间自由转换塞尔达传说旷野之息存档 【免费下载链接】BotW-Save-Manager BOTW Save Manager for Switch and Wii U 项目地址: https://gitcode.com/gh_mirrors/bo/BotW-Save-Manager 你是否曾经为《塞尔达传说:旷野之…

2026/7/6 22:55:53 阅读更多 →
OpenCV 4.9 与 MediaPipe 手势识别:3 种方案在树莓派 5 上的实时性能实测

OpenCV 4.9 与 MediaPipe 手势识别:3 种方案在树莓派 5 上的实时性能实测

OpenCV 4.9 与 MediaPipe 手势识别:树莓派 5 上的三种实时方案性能对比当一块信用卡大小的开发板遇上计算机视觉,会碰撞出怎样的火花?树莓派 5 凭借其升级的四核 Cortex-A76 处理器和 VideoCore VII GPU,正在边缘计算领域掀起新的…

2026/7/6 22:55:53 阅读更多 →
ICM-42688-P与PIC32MX675F512L在工业自动化中的高性能应用

ICM-42688-P与PIC32MX675F512L在工业自动化中的高性能应用

1. ICM-42688-P与PIC32MX675F512L的黄金组合解析在工业自动化和机器人控制领域,传感器与处理器的协同工作能力直接决定了系统性能上限。ICM-42688-P作为TDK InvenSense推出的6轴MEMS运动传感器,与Microchip的PIC32MX675F512L微控制器形成的解决方案&…

2026/7/6 22:55:53 阅读更多 →
openGauss 5.0 在鲲鹏920平台 NUMA 优化实战:事务吞吐提升 30% 的 3 个关键配置

openGauss 5.0 在鲲鹏920平台 NUMA 优化实战:事务吞吐提升 30% 的 3 个关键配置

openGauss 5.0在鲲鹏920平台的NUMA优化实战:3个关键配置实现30%事务吞吐提升在当今数据密集型应用爆发的时代,数据库性能优化已成为企业数字化转型的核心课题。作为国产数据库的领军者,openGauss 5.0与华为鲲鹏920处理器的深度结合&#xff0…

2026/7/6 22:53:52 阅读更多 →

日新闻

H2 与 MySQL 单元测试兼容性:5 个关键 SQL 语句差异与规避方案

H2 与 MySQL 单元测试兼容性:5 个关键 SQL 语句差异与规避方案

H2与MySQL单元测试兼容性:5个关键SQL语句差异与规避方案1. 单元测试中的数据库兼容性挑战在Java开发领域,单元测试是保证代码质量的重要环节。当应用涉及数据库操作时,测试环境的搭建往往成为开发者的痛点。H2数据库因其轻量级、内存模式和快…

2026/7/6 0:01:17 阅读更多 →
Windows任务栏终极清理指南:用RBTray一键隐藏窗口到系统托盘

Windows任务栏终极清理指南:用RBTray一键隐藏窗口到系统托盘

Windows任务栏终极清理指南:用RBTray一键隐藏窗口到系统托盘 【免费下载链接】rbtray A fork of RBTray from http://sourceforge.net/p/rbtray/code/. 项目地址: https://gitcode.com/gh_mirrors/rb/rbtray 你是否厌倦了Windows任务栏上密密麻麻的图标&…

2026/7/6 0:01:17 阅读更多 →
Visual C++ 运行时库一键安装终极指南:告别DLL缺失烦恼

Visual C++ 运行时库一键安装终极指南:告别DLL缺失烦恼

Visual C 运行时库一键安装终极指南:告别DLL缺失烦恼 【免费下载链接】vcredist AIO Repack for latest Microsoft Visual C Redistributable Runtimes 项目地址: https://gitcode.com/gh_mirrors/vc/vcredist 你是否曾经遇到过这样的情况:下载了…

2026/7/6 0:05:19 阅读更多 →

周新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/6 8:11:50 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/6 8:11:52 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/6 6:52:56 阅读更多 →

月新闻