spring boot+sharding-jdbc实现分库分表

shigen日更文章的博客写手,擅长Java、python、vue、shell等编程语言和各种应用程序、脚本的开发。记录成长,分享认知,留住感动。
😅😅最近几天的状态有点不对,所以有几天没有更新了。

当我们的数据量比较大(没接触过)就会考虑一下分库分表的策略。当然分库分表又分为多种策略:

  • 拆分数据库,做到数据的分离(多租户的设计
  • 水平拆分表:类似于数据的分片
  • 垂直拆分表:某些不常用的字段放在另外一张表,我们通过主键关联,在之前的文章mysql表设计规范中也有提到:

在去年疫情的时候,其实shigen就研究了一下这个,只不过当时用的是apache-shardingsphere,采用的是官方的资源包,需要各种安装和配置:

最近发现它其实可以和springboot结合起来使用,于是研究了一下,最后发现很好用。

官方配置文档在这里,需要详细步骤的可以去看下官网的案例和解释。

首先我们创建两个数据库,每个数据库两张表:

sql 复制代码
 -- 数据库1中的user表
 CREATE TABLE ds0.user0
 (
     id   INT PRIMARY KEY COMMENT '用户ID',
     name VARCHAR(50) COMMENT '用户姓名',
     age  INT COMMENT '用户年龄'
 );
 ​
 CREATE TABLE ds0.user1
 (
     id   INT PRIMARY KEY COMMENT '用户ID',
     name VARCHAR(50) COMMENT '用户姓名',
     age  INT COMMENT '用户年龄'
 );
 ​
 -- 数据库2中的user表
 CREATE TABLE ds1.user0
 (
     id   INT PRIMARY KEY COMMENT '用户ID',
     name VARCHAR(50) COMMENT '用户姓名',
     age  INT COMMENT '用户年龄'
 );
 ​
 CREATE TABLE ds1.user1
 (
     id   INT PRIMARY KEY COMMENT '用户ID',
     name VARCHAR(50) COMMENT '用户姓名',
     age  INT COMMENT '用户年龄'
 );

对应关系是这样的:

数据库 数据表 备注
Ds0 User0 数据源1的分表1
Ds0 User1 数据源1的分表2
Ds1 User0 数据源2的分表1
Ds1 User1 数据源2的分表2

shigen之前创建的数据库和数据表用到了类似这样的名字:

demo-ds-0user_1,发现配置起来老有问题了,直接炸了啊。

最后改成不要下划线的才算正常。

在一切准备好之后,我们开始今天的案例。

基于sharding-jdbc实现数据水平切分

引入依赖

xml 复制代码
         <dependency>
             <groupId>org.apache.shardingsphere</groupId>
             <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
             <version>4.1.1</version>
         </dependency>
         <dependency>
             <groupId>com.alibaba</groupId>
             <artifactId>druid</artifactId>
             <version>1.2.8</version>
         </dependency>

这是最核心的依赖,当然,mysql的驱动、mybatis-plus这里也是需要的。

生成基础代码

我们用魔法生成对应的controllerservicedao

编写配置文件

这里我就直接贴上我的配置了,更多的配置可以参考官网。

yaml 复制代码
 spring:
   shardingsphere:
     datasource:
       names: ds0, ds1
       ds0:
         type: com.alibaba.druid.pool.DruidDataSource
         driver-class-name: com.mysql.cj.jdbc.Driver
         url: jdbc:mysql://localhost:3306/ds0
         username: root
         password: 123456
       ds1:
         type: com.alibaba.druid.pool.DruidDataSource
         driver-class-name: com.mysql.cj.jdbc.Driver
         url: jdbc:mysql://localhost:3306/ds1
         username: root
         password: 123456
 ​
     sharding:
       tables:
         user:
           actual-data-nodes: ds$->{0..1}.user$->{0..1}
           table-strategy:
             inline:
               sharding-column: id
               algorithm-expression: user$->{id % 2}
           key-generator:
             column: id
             type: SNOWFLAKE
       binding-tables: user
       broadcast-tables:
       default-database-strategy:
         inline:
           sharding-column: age
           algorithm-expression: ds$->{age % 2}
 ​
     props:
         sql:
           show: true
 mybatis-plus:
   configuration:
     log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
 ​

其实看起来也很有意思的:

  • 采用了druid作为数据库的连接池工具,它自带后台,可以监控我们的sql
  • 我们表的拆分根据的是user.id,id是偶数就放在user0,奇放在user1
  • 数据库的拆分根据的是user.age,这里的age是偶数,放在ds0,反之放在ds1
  • 打印详细的sql执行语句

就这些,其实已经帮我们把复杂的配置简单了。现在,我们写一个测试类测试吧。

测试类测试

scss 复制代码
     @Test
     public void saveTest() {
         for (int i = 100; i < 120; i++) {
             User user = new User().setId(i+10000).setName("shigen-" + i).setAge(RandomUtil.randomInt(5, 100));
             userMapper.insert(user);
         }
     }

1-99的我已经测试了。

观察一下运行的结果:

我们再到数据库看一下:

很符合预期啊,年龄为奇数的在ds0,id为偶数的在user0;表明我们的测试顺利。

其实还是那句话,具体场景具体的分析,没有这么大的数据量,分库分表反而是复杂、完全没必要的设计。也希望提供一种技术选型和参考。

当然,sharding-jdbc还支持读写分离,正好shigen之前也有一个文章是关于springboot+mybtais-plus实现读写分离的,那就期待下期的文章吧!


以上就是今天分享的全部内容了,觉得不错的话,记得点赞 在看 关注支持一下哈,您的鼓励和支持将是shigen坚持日更的动力。同时,shigen在多个平台都有文章的同步,也可以同步的浏览和订阅:

平台 账号 链接
CSDN shigen01 shigen的CSDN主页
知乎 gen-2019 shigen的知乎主页
掘金 shigen01 shigen的掘金主页
腾讯云开发者社区 shigen shigen的腾讯云开发者社区主页
微信公众平台 shigen 公众号名:shigen

shigen一起,每天不一样!

相关推荐
SomeB1oody29 分钟前
【Rust自学】7.4. use关键字 Pt.2 :重导入与换国内镜像源教程
开发语言·后端·rust
新知图书33 分钟前
Rust编程与项目实战-箱
开发语言·后端·rust
SomeB1oody37 分钟前
【Rust自学】7.3. use关键字 Pt.1:use的使用与as关键字
开发语言·后端·rust
minstbe1 小时前
WEB开发 - Flask 入门:Jinja2 模板语法进阶 Python
后端·python·flask
无名之逆1 小时前
lombok-macros
开发语言·windows·后端·算法·面试·rust·大学期末
m0_748247802 小时前
SpringBoot集成Flowable
java·spring boot·后端
散一世繁华,颠半世琉璃2 小时前
SpringBoot揭秘:URL与HTTP方法如何定位到Controller
spring boot·后端·http
安晴晚风3 小时前
从0开始在linux服务器上部署SpringBoot和Vue
linux·运维·前端·数据库·后端·运维开发
海绵波波1079 小时前
flask后端开发(10):问答平台项目结构搭建
后端·python·flask
网络风云10 小时前
【魅力golang】之-反射
开发语言·后端·golang