SpringBoot+MybatisPlus+Mysql+Sharding-JDBC分库分表实践
一、序言
在实际业务中,单表数据增长较快,很容易达到数据瓶颈,比如单表百万级别数据量。当数据量继续增长时,数据的查询性能即使有索引的帮助下也不尽如意,这时可以引入数据分库分表技术。
本文将基于SpringBoot+MybatisPlus+Sharding-JDBC+Mysql实现企业级分库分表。
1、组件及版本选择
![]() |
![]() |
![]() |
![]() |
|---|---|---|---|
| SpringBoot 2.6.x | MybatisPlus 3.5.0 | Sharding-JDBC 4.1.1 | Mysql 5.7.35 |
2、预期目标
- 使用上述组件实现分库分表,简化起见只讨论分表技术
- 完成分表后的逻辑表与物理表间的增删查改
- 引入逻辑删除和使用MybatisPlus内置分页技术
完整项目源码访问地址。
二、代码实现
为了简化分表复杂性,专注于分表整体实现,简化分表逻辑:按照UserId的奇偶属性分别进行分表。以订单表这一典型场景为例,一般来说有关订单表,通常具有如下共性行为:
- 创建订单记录
- 查询XX用户的订单列表
- 查询XX用户的订单列表(分页)
- 查询XX订单详情
- 修改订单状态
- 删除订单(逻辑删除)
接下来通过代码实现上述目标。
(一)素材准备
1、实体类
@Data
@TableName("bu_order")
public class Order {
@TableId
private Long orderId;
private Integer orderType;
private Long userId;
private Double amount;
private Integer orderStatus;
@TableLogic
@JsonIgnore
private Boolean deleted;
}
2、Mapper类
@Mapper
public interface OrderMapper extends BaseMapper<Order> {
}
3、全局配置文件
spring:
config:
use-legacy-processing: true
shardingsphere:
datasource:
ds1:
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
url: jdbc:mysql://127.0.0.1:3306/sharding-jdbc2?serverTimezone=UTC
username: root
password: 123456
names: ds1
props:
sql:
show: true
sharding:
tables:
bu_order:
actual-data-nodes: ds1.bu_order_$->{0..1}
key-generator:
column: order_id
type: SNOWFLAKE
table-strategy:
inline:
algorithm-expression: bu_order_${user_id%2}
sharding-column: user_id
(二)增删查改
1、保存数据
由于依据主键的奇偶属性对原表分表,分表后每张表的数据量是分表前的二分之一。根据需要也可以自定义分表数量(比如10张),新分表后的数据量是不分表前的十分之一。
@Test
public void addOrders() {
for (long i = 1; i <= 10; i++) {
Order order = new Order();
order.setOrderId(i);
order.setOrderType(RandomUtil.randomEle(Arrays.asList(1, 2)));
order.setUserId(RandomUtil.randomEle(Arrays.asList(101L, 102L, 103L)));
order.setAmount(1000.0 * i);
orderMapper.insert(order);
}
}
2、查询列表数据
查询指定用户的订单列表。
@GetMapping("/list")
public AjaxResult list(Order order) {
LambdaQueryWrapper<Order> wrapper = Wrappers.lambdaQuery(order);
return AjaxResult.success(orderMapper.selectList(wrapper));
}
3、分页查询数据
分页查询指定用户的订单列表
@GetMapping("/page")
public AjaxResult page(Page<Order> page, Order order) {
return AjaxResult.success(orderMapper.selectPage(page, Wrappers.lambdaQuery(order)));
}
4、查询详情
通过订单ID查询订单详情。
@GetMapping("/detail/{orderId}")
public AjaxResult detail(@PathVariable Long orderId) {
return AjaxResult.success(orderMapper.selectById(orderId));
}
5、删除数据
通过订单ID删除订单(逻辑删除)
@DeleteMapping("/delete/{orderId}")
public AjaxResult delete(@PathVariable Long orderId) {
return AjaxResult.success(orderMapper.deleteById(orderId));
}
6、修改数据
修改数据一般涉及部分列,比如修改订单表的订单状态等。
@PutMapping("/edit")
public AjaxResult edit(@RequestBody Order order) {
return AjaxResult.success(orderMapper.updateById(order));
}
三、理论分析
1、选择分片列
选择分片列是经过精心对比后确定的,对于订单类场景,需要频繁以用户ID为查询条件筛选数据,因此将同一个用户的订单数据存放在一起有利于提高查询效率。
2、扩容
当分表后的表数据快速增长,可以预见即将达到瓶颈时,需要对分表进行扩容,扩容以2倍的速率进行,扩容期间需要迁移数据,工作量相对可控。
SpringBoot+MybatisPlus+Mysql+Sharding-JDBC分库分表实践的更多相关文章
- mysql、oracle分库分表方案之sharding-jdbc使用(非demo示例)
选择开源核心组件的一个非常重要的考虑通常是社区活跃性,一旦项目团队无法进行自己后续维护和扩展的情况下更是如此. 至于为什么选择sharding-jdbc而不是Mycat,可以参考知乎讨论帖子https ...
- Mysql中的分库分表
mysql中的分库分表分库:减少并发问题分表:降低了分布式事务分表 1.垂直分表 把其中的不常用的基础信息提取出来,放到一个表中通过id进行关联.降低表的大小来控制性能,但是这种方式没有解决高数据量带 ...
- MySQL纯透明的分库分表技术还没有
MySQL纯透明的分库分表技术还没有 种树人./oneproxy --proxy-address=:3307 --admin-username=admin --admin-password=D033 ...
- Mycat安装并实现mysql读写分离,分库分表
Mycat安装并实现mysql读写分离,分库分表 一.安装Mycat 1.1 创建文件夹 1.2 下载 二.mycat具体配置 2.1 server.xml 2.2 schema.xml 2.3 se ...
- Docker安装Mycat并实现mysql读写分离,分库分表
Docker安装Mycat并实现mysql读写分离,分库分表 一.拉取mycat镜像 二.准备挂载的配置文件 2.1 创建文件夹并添加配置文件 2.1.1 server.xml 2.1.2 serve ...
- MyCat | 分库分表实践
引言 先给大家介绍2个概念:数据的切分(Sharding)根据其切分规则的类型,可以分为两种切分模式. 切分模式 一种是按照不同的表(或者Schema)来切分到不同的数据库(主机)之上,这种切可以称之 ...
- MariaDB Spider 数据库分库分表实践
分库分表 一般来说,数据库分库分表,有以下做法: 按哈希分片:根据一条数据的标识计算哈希值,将其分配到特定的数据库引擎中: 按范围分片:根据一条数据的标识(一般是值),将其分配到特定的数据库引擎中: ...
- mycat+ mysql集群 分库分表
mycat介绍Mycat数据库分库分表中间件国内最活跃的.性能最好的开源数据库中间件!Mycat关键特性关键特性支持SQL92标准支持MySQL.Oracle.DB2.SQL Server.Postg ...
- 【ShardingSphere技术专题】「ShardingJDBC」SpringBoot之整合ShardingJDBC实现分库分表(JavaConfig方式)
前提介绍 ShardingSphere介绍 ShardingSphere是一套开源的分布式数据库中间件解决方案组成的生态圈,它由Sharding-JDBC.Sharding-Proxy和Shardin ...
随机推荐
- 使用.NET 6开发TodoList应用(29)——实现静态字符串本地化功能
系列导航及源代码 使用.NET 6开发TodoList应用文章索引 需求 在开发一些需要支持多种语言的应用程序时,我们需要根据切换的语言来对应展示一些静态的字符串字段,在本文中我们暂时不去讨论如何结合 ...
- ubuntu18.04下取消中键复制粘贴功能
Q: armlinux开发,主机采用ubuntu18.04操作系统,使用过程中关于鼠标中键有如下操作现象, 操作: 1.选中文本, 2.将鼠标光标定位到要插入的位置 3.按下鼠标中键 现象:将自动复制 ...
- CUDA 入门(转)
CUDA(Compute Unified Device Architecture)的中文全称为计算统一设备架构.做图像视觉领域的同学多多少少都会接触到CUDA,毕竟要做性能速度优化,CUDA是个很重要 ...
- Java高效开发-远程debug
1.前言 "这怎么回事?在本地还好好,放到服务器就不行了.这该怎么排查,日志也看不出来啥呀",日常开发中经常会出现这种问题,这时候就可以尝试idea远程debug的模式试试 2.使 ...
- 判断jquery类库是否加载,如未加载则加载。
本人所有文章使用到的东西均在"渭南电脑维修网"网站中得以实现和应用,还请大家参考. 抄写别人网站的同时,N多不同的网站,势必有N多的css.javascript引用文件都会重复引用 ...
- golang中通过bufio和os包读取终端中输入的一行带空格的数据
1. 如果读取不带空格的数据可以使用fmt.Scan或fmt.Scanln读取一个或多个值,但是不能读取带空格的数据,可以使用bufio和os两个包结合 package main import ( & ...
- IDEA包名分层问题
解决办法: 将默认的"Hide empty Middle Packages"或者"compact middle packages"勾选项去掉,这样就不会把中间空 ...
- linux用户密码过期导致命令执行失败
背景介绍: 使用zabbix调用系统命令,检查时间同步,发现一直在报错,root 用户执行无异常,问题还是出现zabbix用户上面. [zabbix@test-10-12 ~]$ sudo ntpda ...
- 字体替换 re.sub
dic={'hqo3r': '迎', 'hq6ic': '名', 'hq7yw': '头', 'hq1lk': '新', 'hqpe1': '肇'} content=''' 总体hqo3r则,错的注( ...
- maven中profiles使用详解
使用的场景 常常遇到一些项目中多环境切换的问题.比如在开发过程中用到开发环境,在测试中使用测试环境,在生产中用生产环境的情况.springboot中提供了 spring.profile.active的 ...



