news 2026/6/1 9:11:07

Spring Boot + ShardingSphere 介绍

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Spring Boot + ShardingSphere 介绍

目录

  • 前言
  • 一、为什么需要 ShardingSphere
  • 二、什么是 ShardingSphere
  • 三、ShardingSphere 解决了什么问题
  • 四、ShardingSphere 的核心概念
    • 1. 逻辑表
    • 2. 真实表
    • 3. 分片键
    • 4. 分片算法
  • 五、Spring Boot 集成 ShardingSphere
    • 1. 引入依赖
    • 2. 配置数据源
    • 3. 是否还需要 spring.datasource
  • 六、配置真实表
  • 七、按月份分表
    • 1. 配置分片策略
    • 2. sharding-column 是什么
    • 3. 必须有 create_time 字段吗
  • 八、配置时间分片算法
    • 1. datetime-pattern
    • 2. datetime-lower
    • 3. datetime-upper
    • 4. sharding-suffix-pattern
    • 5. datetime-interval-unit
  • 九、MyBatis 和 MyBatis Plus 如何使用
    • 1. Mapper 不需要修改
    • 2. XML 不需要修改
    • 3. ShardingSphere 自动改写 SQL
  • 十、查询如何路由
    • 1. 精准路由
    • 2. 范围路由
    • 3. 全路由
  • 十一、每个 SQL 都必须带分片键吗
  • 十二、ShardingSphere 会自动创建表吗
  • 十三、如何自动创建分表
    • 1. 推荐方案
    • 2. 定时任务创建
    • 3. Flyway 或 Liquibase
  • 十四、生产环境如何设计分表
    • 1. 单纯按月份分表
    • 2. 按用户 Hash 分表
    • 3. 时间 + Hash
  • 十五、ShardingSphere 的优缺点
    • 优点
    • 缺点
  • 十六、总结

前言

随着业务的发展,订单表、支付表、交易流水表等核心业务表的数据量会不断增长。当单表数据达到数千万甚至上亿级别时,查询性能、索引维护、数据备份和数据库扩容等问题都会逐渐显现。

为了解决单表数据量过大的问题,互联网系统通常会采用分库分表方案,将数据按照一定规则拆分到多个数据库或数据表中。然而,分库分表之后也会带来新的挑战,例如如何确定数据应该存储到哪张表、如何跨表查询数据、如何降低业务代码的改造成本等。

ShardingSphere正是为了解决这些问题而诞生的。它能够在应用层和数据库之间提供透明的分片能力,让开发人员仍然像操作普通数据表一样进行开发,而无需关心底层的数据路由和 SQL 改写过程。

本文将结合 Spring Boot 和 MyBatis 项目,从分库分表的背景开始,逐步介绍 ShardingSphere 的核心概念、工作原理、项目集成方式、分片算法配置以及实际项目中的使用技巧,帮助读者快速掌握 ShardingSphere 的基本使用与设计思路。

shardingsphere官网

shardingsphere HitHub地址

一、为什么需要 ShardingSphere

随着业务发展,订单表、支付表、流水表的数据量会越来越大。

例如有一张支付订单表:

CREATETABLEpay_info(idBIGINTPRIMARYKEY,order_noVARCHAR(64),user_idBIGINT,amountDECIMAL(18,2),create_timeDATETIME);

如果每天产生 100 万条数据:

100万/天 ≈ 3000万/月 ≈ 3.6亿/年

几年之后,单表可能达到几十亿数据。

此时会出现很多问题:

  • 查询变慢
  • 索引变大
  • 备份恢复困难
  • DDL操作耗时
  • 数据迁移困难

因此需要进行:

分库分表

最常见的方案:

  • 按时间分表
  • 按用户分表
  • 按订单号分表

而目前 Java 生态中最主流的分库分表框架之一就是 Apache ShardingSphere。


二、什么是 ShardingSphere

ShardingSphere 是 Apache 顶级项目。

它是一套数据库中间件生态,主要功能包括:

  • 分库分表
  • 读写分离
  • 分布式事务
  • 数据加密
  • SQL 路由
  • SQL 改写

在 Spring Boot 项目中最常见的是:

ShardingSphere-JDBC

其架构如下:

MyBatis ↓ ShardingSphere ↓ MySQL

对于业务代码来说:

感知不到分表的存在

三、ShardingSphere 解决了什么问题

假设数据库中有以下表:

pay_info_202601 pay_info_202602 pay_info_202603 ...

程序中仍然写:

select*frompay_info

或者:

payInfoMapper.insert(payInfo);

增删改查时 ShardingSphere 会自动帮你改写 SQL。

例如:

createTime=2026-05-15

自动路由:

insertintopay_info_202605

开发人员完全不需要手动判断表名。


四、ShardingSphere 的核心概念

1. 逻辑表

程序中看到的表:

pay_info

称为逻辑表。

例如:

select*frompay_info

2. 真实表

数据库真正存在的表:

pay_info_202601 pay_info_202602 pay_info_202603

称为真实表。


3. 分片键

决定数据进入哪张表的字段。

例如:

create_time

或者:

user_id

或者:

order_no

都可以作为分片键。


4. 分片算法

根据分片键计算目标表。

例如:

2026-05-15

计算得到:

pay_info_202605

五、Spring Boot 集成 ShardingSphere

1. 引入依赖

<dependency><groupId>org.apache.shardingsphere</groupId><artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId></dependency>

2. 配置数据源

spring:shardingsphere:datasource:names:dsds:type:com.zaxxer.hikari.HikariDataSourcedriver-class-name:com.mysql.cj.jdbc.Driverurl:jdbc:mysql://localhost:3306/testusername:rootpassword:root

这里的:

url username password

就是实际数据库连接配置。


3. 是否还需要 spring.datasource

上面在 shardingsphere 下已经配置了数据源了,是否还需要 spring.datasource ?

通常不需要。

不要同时配置:

spring:datasource:

和:

spring:shardingsphere:datasource:

否则可能出现:

NoUniqueBeanDefinitionException

因为 Spring 中会存在多个 DataSource Bean。


六、配置真实表

假设数据库已经存在:

pay_info_202601 pay_info_202602 ... pay_info_203012

配置如下:

spring:shardingsphere:rules:sharding:tables:pay_info:actual-data-nodes:ds.pay_info_$->{202601..203012}

含义:

逻辑表: pay_info 真实表: pay_info_202601 pay_info_202602 ... pay_info_203012

七、按月份分表

1. 配置分片策略

table-strategy:standard:sharding-column:create_timesharding-algorithm-name:pay-info-month

2. sharding-column 是什么

表示:

根据哪个字段决定路由

例如:

sharding-column:create_time

表示:

根据 create_time 决定数据进入哪张表

例如:

2026-05-20

自动进入:

pay_info_202605

3. 必须有 create_time 字段吗

不一定。

可以使用:

sharding-column:pay_time

或者:

sharding-column:order_time

只要能够表达时间即可。


八、配置时间分片算法

sharding-algorithms:pay-info-month:type:INTERVALprops:datetime-pattern:yyyy-MM-dd HH:mm:ssdatetime-lower:2025-01-01 00:00:00datetime-upper:2030-12-31 23:59:59sharding-suffix-pattern:yyyyMMdatetime-interval-unit:MONTHS

1. datetime-pattern

时间格式。

yyyy-MM-dd HH:mm:ss

例如:

2026-05-1815:20:30

2. datetime-lower

开始时间:

2025-01-01 00:00:00

3. datetime-upper

结束时间:

2030-12-31 23:59:59

4. sharding-suffix-pattern

表后缀格式。

例如:

yyyyMM

生成:

pay_info_202605

如果:

yyyy_MM

生成:

pay_info_2026_05

5. datetime-interval-unit

分片粒度。

按月:

MONTHS

生成:

pay_info_202605 pay_info_202606

按天:

DAYS

生成:

pay_info_20260501 pay_info_20260502

按年:

YEARS

生成:

pay_info_2025 pay_info_2026

九、MyBatis 和 MyBatis Plus 如何使用

1. Mapper 不需要修改

例如:

@MapperpublicinterfacePayInfoMapper{PayInfoselectById(Longid);}

2. XML 不需要修改

仍然写:

<selectid="selectById">select * from pay_info where id = #{id}</select>

不要写:

pay_info_202605

也不要写:

pay_info_202606

统一写:

pay_info

即可。


3. ShardingSphere 自动改写 SQL

程序:

select*frompay_info

实际执行:

select*frompay_info_202605

或者:

select*frompay_info_202605unionallselect*frompay_info_202606

十、查询如何路由

1. 精准路由

例如:

select*frompay_infowherecreate_time>='2026-05-01'andcreate_time<'2026-06-01'

只查询:

pay_info_202605

性能最好。


2. 范围路由

例如:

select*frompay_infowherecreate_timebetween'2026-05-01'and'2026-07-31'

查询:

pay_info_202605 pay_info_202606 pay_info_202607

3. 全路由

例如:

select*frompay_infowherestatus=1

没有分片键:

create_time

ShardingSphere 无法判断目标表。

于是:

pay_info_202601 pay_info_202602 ... pay_info_203012

全部查询。

这就是:

全路由

性能极差。


十一、每个 SQL 都必须带分片键吗

不是必须。

可以正常执行。

但是:

不带分片键 = 全路由 = 查询所有分表

因此在设计表结构时:

高频查询条件 最好就是分片键

这样性能最高。


十二、ShardingSphere 会自动创建表吗

不会。

ShardingSphere 负责:

SQL路由

不负责:

创建表

例如:

insertintopay_info

路由到:

pay_info_202606

如果:

pay_info_202606

不存在。

直接报错:

Table doesn't exist

十三、如何自动创建分表

1. 推荐方案

提前创建未来几年表。

例如:

pay_info_202601 ... pay_info_203012

一次建好即可。


2. 定时任务创建

假设每月1号创建未来三个月的表

(1)定时任务

//每个月的 1 号凌晨 2 点整执行一次@Scheduled(cron="0 0 2 1 * ?")publicvoidcreateFutureTables(){//循环三次创建未来三个月的表for(inti=1;i<=3;i++){LocalDatemonth=LocalDate.now().plusMonths(i);//检查表是否存在,不存在则创建createTableIfNotExists(month);}}

(2)模板表

一般会准备一个模板表:

CREATETABLEpay_info_template(idBIGINTPRIMARYKEY,order_noVARCHAR(64),amountDECIMAL(18,2),create_timeDATETIME,KEYidx_create_time(create_time));

(3) 使用 JdbcTemplate 创建表

@AutowiredprivateJdbcTemplatejdbcTemplate;privatevoidcreateTableIfNotExists(LocalDatemonth){StringtableName=String.format("pay_info_%d_%02d",month.getYear(),month.getMonthValue());Stringsql="CREATE TABLE IF NOT EXISTS "+tableName+" LIKE pay_info_template";jdbcTemplate.execute(sql);}

效果:

假设 当前是2026-05,定时任务会执行:

CREATETABLEIFNOTEXISTSpay_info_202606LIKEpay_info_template;CREATETABLEIFNOTEXISTSpay_info_202607LIKEpay_info_templateCREATETABLEIFNOTEXISTSpay_info_202608LIKEpay_info_template

最终创建了:

pay_info_2026_06 pay_info_2026_07 pay_info_2026_08

3. Flyway 或 Liquibase

使用数据库版本管理工具自动创建。


十四、生产环境如何设计分表

1. 单纯按月份分表

pay_info_202605 pay_info_202606 pay_info_202607

适合:

按时间查询较多

2. 按用户 Hash 分表

pay_info_00 pay_info_01 ... pay_info_63

路由:

userId%64

适合:

根据用户查询较多

3. 时间 + Hash

大型支付系统最常见。

例如:

pay_info_202605_00 pay_info_202605_01 ... pay_info_202605_15

优势:

  • 控制单表大小
  • 查询效率高
  • 扩展能力强

十五、ShardingSphere 的优缺点

优点

  • 对业务代码侵入小
  • MyBatis 基本不用改
  • 自动路由
  • 自动聚合结果
  • 支持读写分离
  • 支持分布式事务
  • 支持分库分表

缺点

  • 配置复杂
  • SQL 不宜过于复杂
  • 跨分片查询成本高
  • 全路由性能差
  • 分页查询需要特别注意

十六、总结

ShardingSphere 本质上是一个数据库中间层。

对于开发人员来说:

仍然操作逻辑表 pay_info

对于数据库来说:

实际访问真实表 pay_info_202605 pay_info_202606

其核心思想只有一句话:

开发只关心逻辑表, ShardingSphere负责将SQL路由到正确的真实表。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/1 9:08:35

日常用 AI 大模型总折腾?CenToken 一站式聚合真的省心

现在不管是日常写文案、做学习总结&#xff0c;还是处理办公文档&#xff0c;大家都会用到 AI 大模型。我自己用了快一年各类大模型&#xff0c;最大的感受就是平台太多、切换太麻烦&#xff0c;完全影响使用效率。很多人应该和我一样&#xff0c;手机和电脑里存着好几个大模型…

作者头像 李华
网站建设 2026/6/1 9:03:49

Python 零基础第一周入门学习笔记

1. 安装 Python 1.1 下载 Python &#xff08;1&#xff09;打开官网 https://www.python.org/downloads/&#xff0c;点击 Downloads&#xff0c;下载最新的 Python 3.14.5。1.2 安装 Python &#xff08;2&#xff09;双击 python-3.14.5-amd64.exe 安装 Python。 安装的时候…

作者头像 李华
网站建设 2026/6/1 9:01:44

2026年南宁美食排行榜,这些地道美味你吃过几个?

走在南宁的街头&#xff0c;你会发现一个有趣的现象&#xff1a;那些排长队的店&#xff0c;往往是藏在小巷深处、门面不大的老店。它们没有华丽的装修&#xff0c;没有铺天盖地的广告&#xff0c;只是靠着“一碗粉、一份饺子”的坚守&#xff0c;成了街坊邻居口口相传的“排队…

作者头像 李华
网站建设 2026/6/1 9:00:03

【周报】液冷板块集体跌停,但我在算一笔账

2026年5月25日&#xff0d;5月31日 AI与液冷这周为什么值得看5月21日&#xff0c;液冷概念股集体崩了。汉钟精机跌停&#xff0c;飞龙股份跌超7%&#xff0c;大元泵业跌停。整个液冷板块单日净流出超30亿。但同一天&#xff0c;产业资本悄悄扫货&#xff1a;中车资本独家投资液…

作者头像 李华
网站建设 2026/6/1 8:58:02

2iterable iterator 可迭代对象与迭代器

1. iterable 可迭代对象支持 for 遍历不支持 next()内置方法&#xff1a;__iter__常见可迭代对象list、tuple、str、set、range、map、filter、open(file)、iterator、generator转为迭代器语法&#xff1a;iter(可迭代对象)本质&#xff1a;额外增加 __next__ 方法2. iterator …

作者头像 李华