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

sharding-jdbc实现分库分表

shigen日更文章的博客写手,擅长Java、python、vue、shell等编程语言和各种应用程序、脚本的开发。记录成长,分享认知,留住感动。

😅😅最近几天的状态有点不对,所以有几天没有更新了。

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

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

一张表的字段不要过多

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

apache-shardingsphere

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

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

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

-- 数据库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 '用户年龄'
);

对应关系是这样的:

数据库数据表备注
Ds0User0数据源1的分表1
Ds0User1数据源1的分表2
Ds1User0数据源2的分表1
Ds1User1数据源2的分表2

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

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

踩坑记录

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

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

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

引入依赖
        <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

生成代码

编写配置文件

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

spring:shardingsphere:datasource:names: ds0, ds1ds0:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/ds0username: rootpassword: 123456ds1:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/ds1username: rootpassword: 123456sharding:tables:user:actual-data-nodes: ds$->{0..1}.user$->{0..1}table-strategy:inline:sharding-column: idalgorithm-expression: user$->{id % 2}key-generator:column: idtype: SNOWFLAKEbinding-tables: userbroadcast-tables:default-database-strategy:inline:sharding-column: agealgorithm-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执行语句

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

测试类测试
    @Testpublic 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的我已经测试了。

观察一下运行的结果:

查看到的实际的sql

我们再到数据库看一下:

实际的数据

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

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

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


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

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

shigen一起,每天不一样!

相关文章:

sharding-jdbc实现分库分表

shigen日更文章的博客写手&#xff0c;擅长Java、python、vue、shell等编程语言和各种应用程序、脚本的开发。记录成长&#xff0c;分享认知&#xff0c;留住感动。 &#x1f605;&#x1f605;最近几天的状态有点不对&#xff0c;所以有几天没有更新了。 当我们的数据量比较大…...

JDK中lock锁的机制,其底层是一种无锁的架构实现的,公平锁和非公平锁

简述JDK中lock锁的机制&#xff0c;其底层是一种无锁的架构实现的&#xff0c;是否知道其是如何实现的 synchronized与lock lock是一个接口&#xff0c;而synchronized是在JVM层面实现的。synchronized释放锁有两种方式&#xff1a; 获取锁的线程执行完同步代码&#xff0c;…...

c++通过serial库进行上下位机通信

​编辑 风紊 现役大学牲&#xff0c;半退休robomaster视觉队员 写在前面 本文章主要介绍的是如何通过开源的serial库和虚拟串口实现上位机和下位机通信。 需求 假设下位机有这样一个数据报发送给上位机 struct DataRecv {char start s;TeamColor color TeamColor::Blu…...

【傻瓜级JS-DLL-WINCC-PLC交互】7.​C#直连PLC并读取PLC数据

思路 JS-DLL-WINCC-PLC之间进行交互&#xff0c;思路&#xff0c;先用Visual Studio创建一个C#的DLL控件&#xff0c;然后这个控件里面嵌入浏览器组件&#xff0c;实现JS与DLL通信&#xff0c;然后DLL放入到WINCC里面的图形编辑器中&#xff0c;实现DLL与WINCC的通信。然后PLC与…...

指针常量和常量指针的区别

文章目录 指针常量常量指针即是指针常量又是常量指针 指针常量 指针常量的本质是常量&#xff0c;表示的是 这个指针所指向的地址不能发生改变。即指针变量的值&#xff08;即地址值&#xff09;不能发生修改。但是指针所指向的那块内存里的值是可以修改的。 注意&#xff1a;…...

离散化算法总结

离散化是将大范围的数字映射到小范围的区间内&#xff0c;适用于稀疏的区间。 两个问题需要考虑&#xff1a; 1. 原数组中可能有重复元素&#xff0c;需要去重。 2. 如何算出离散化后的值&#xff08;离散化后保序&#xff0c;使用二分&#xff09;。 题目链接&#xff1a; …...

【海思SS528 | VO】MPP媒体处理软件V5.0 | VO模块编程总结

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; &#x1f923;本文内容&#x1f923;&a…...

逻辑卷管理器lvm

啥意思&#xff0c;个人理解就是可以将物理分区合并一起组成大的磁盘&#xff0c;也可以移除其中的某个分区。 有四个概念需要了解下 PV&#xff0c;物理卷&#xff0c;VG 卷用户组&#xff0c;PE物理扩展块&#xff0c;LV逻辑卷 p物理&#xff0c;v卷&#xff0c;g用户组&a…...

函数声明后的“ - >”是什么?

这种语法的优势之一是可以在函数的返回类型中使用函数参数&#xff0c;使得返回类型更灵活。 先来看一个使用尾返回类型的例子&#xff1a; #include <iostream> auto add(int a, int b) -> int {return a b; }int main() {std::cout << add(3, 4) <<…...

51爱心流水灯32灯炫酷代码

源代码摘自远眺883的文章&#xff0c;大佬是30个灯的&#xff0c;感兴趣的铁汁们可以去看看哦~&#xff08;已取得原作者的许可&#xff09;&#xff1a;基于STC89C51单片机设计的心形流水灯软件代码部分_单片机流水灯代码_远眺883的博客-CSDN博客 由于博主是个小菜鸡&#xff…...

将不同时间点的登录状态记录转化为不同时间段的相同登录状态SQL求解

题目 有不同时间点的登录状态记录表state_log如下 请使用sql将其转化为如下表的不同时间段的相同登录状态记录 思路分析&#xff1a; 此类问题需要用到lag或lead函数取上下行对应的数据&#xff0c;然后对前后结果做比较打标签&#xff08;0或1&#xff09;&#xff0c;再…...

正则表达式与SQL数据库教程

使用正则表达式通过用例查询 Postgres 数据库&#xff1a; 正则表达式&#xff08;又名 Regex&#xff09; 正则表达式是一个强大的工具&#xff0c;广泛用于模式匹配和文本操作。 几乎所有编程语言都支持它们&#xff0c;并且经常用于文本提取、搜索和匹配文本等用例。 正则…...

HTML_web扩展标签

1.表格标签 2.增强表头表现 4.表格属性&#xff08;实际不常用&#xff09; 结构标签&#xff1a; 合并单元格&#xff1a; 更多请查看主页...

论文阅读:Distributed Initialization for VVIRO with Position-Unknown UWB Network

前言 Distributed Initialization for Visual-Inertial-Ranging Odometry with Position-Unknown UWB Network这篇论文是发表在ICRA 2023上的一篇文章&#xff0c;本文提出了一种基于位置未知UWB网络的一致性视觉惯性紧耦合优化测距算法( DC-VIRO )的分布式初始化方法。 对于…...

scrapy爬虫中间件和下载中间件的使用

一、关于中间件 之前文章说过&#xff0c;scrapy有两种中间件&#xff1a;爬虫中间件和下载中间件&#xff0c;他们的作用时间和位置都不一样&#xff0c;具体区别如下&#xff1a; 爬虫中间件&#xff08;Spider Middleware&#xff09; 作用&#xff1a; 爬虫中间件主要负…...

手敲单链表,简单了解其运行逻辑

1. 链表 1.1 结构组成 链表是一种物理存储结构上非连续存储结构&#xff0c;数据元素的逻辑顺序是通过链表中的引用链接次序实现的 。 链表的结构如下图所示&#xff0c;是由很多个节点相互通过引用来连接而成的&#xff1b;每一个节点由两部分组成&#xff0c;分别数据域&…...

Redis RDB

基于内存的 Redis, 数据都是存储在内存中的。 那么如果重启的话, 数据就会丢失。 为了解决这个问题, Redis 提供了 2 种数据持久化的方案: RDB 和 AOF。 RDB 是 Redis 默认的持久化方案。当满足一定条件的时候, 会把当前内存中的数据写入磁盘, 生成一个快照文件 dump.rdb。Redi…...

Elasticsearch一些函数查询

1. 根据价格分组统计数量&#xff0c;每组区间为2000&#xff0c; filter_pathaggregations 设置查询结果只展示函数结果 也有date_histogram函数根据日期分组等等 GET order/_search?filter_pathaggregations {"aggs": {"hist_price": {"histogr…...

竞赛选题 : 题目:基于深度学习的水果识别 设计 开题 技术

1 前言 Hi&#xff0c;大家好&#xff0c;这里是丹成学长&#xff0c;今天做一个 基于深度学习的水果识别demo 这是一个较为新颖的竞赛课题方向&#xff0c;学长非常推荐&#xff01; &#x1f9ff; 更多资料, 项目分享&#xff1a; https://gitee.com/dancheng-senior/pos…...

Linux expect命令详解

在Linux系统中&#xff0c;expect 是一款非常有用的工具&#xff0c;它允许用户自动化与需要用户输入进行交互的程序。本文将深入探讨expect命令的基本语法、使用方法以及一些最佳实践。 什么是Expect命令&#xff1f; expect 是一个用于自动化交互式进程的工具。它的主要功能…...

CTF show Web 红包题第六弹

提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框&#xff0c;很难让人不联想到SQL注入&#xff0c;但提示都说了不是SQL注入&#xff0c;所以就不往这方面想了 ​ 先查看一下网页源码&#xff0c;发现一段JavaScript代码&#xff0c;有一个关键类ctfs…...

DAY 47

三、通道注意力 3.1 通道注意力的定义 # 新增&#xff1a;通道注意力模块&#xff08;SE模块&#xff09; class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...

JVM垃圾回收机制全解析

Java虚拟机&#xff08;JVM&#xff09;中的垃圾收集器&#xff08;Garbage Collector&#xff0c;简称GC&#xff09;是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象&#xff0c;从而释放内存空间&#xff0c;避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...

测试markdown--肇兴

day1&#xff1a; 1、去程&#xff1a;7:04 --11:32高铁 高铁右转上售票大厅2楼&#xff0c;穿过候车厅下一楼&#xff0c;上大巴车 &#xffe5;10/人 **2、到达&#xff1a;**12点多到达寨子&#xff0c;买门票&#xff0c;美团/抖音&#xff1a;&#xffe5;78人 3、中饭&a…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?

论文网址&#xff1a;pdf 英文是纯手打的&#xff01;论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误&#xff0c;若有发现欢迎评论指正&#xff01;文章偏向于笔记&#xff0c;谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...

vue3 字体颜色设置的多种方式

在Vue 3中设置字体颜色可以通过多种方式实现&#xff0c;这取决于你是想在组件内部直接设置&#xff0c;还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法&#xff1a; 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...

反射获取方法和属性

Java反射获取方法 在Java中&#xff0c;反射&#xff08;Reflection&#xff09;是一种强大的机制&#xff0c;允许程序在运行时访问和操作类的内部属性和方法。通过反射&#xff0c;可以动态地创建对象、调用方法、改变属性值&#xff0c;这在很多Java框架中如Spring和Hiberna…...

QT: `long long` 类型转换为 `QString` 2025.6.5

在 Qt 中&#xff0c;将 long long 类型转换为 QString 可以通过以下两种常用方法实现&#xff1a; 方法 1&#xff1a;使用 QString::number() 直接调用 QString 的静态方法 number()&#xff0c;将数值转换为字符串&#xff1a; long long value 1234567890123456789LL; …...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心

当仓库学会“思考”&#xff0c;物流的终极形态正在诞生 想象这样的场景&#xff1a; 凌晨3点&#xff0c;某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径&#xff1b;AI视觉系统在0.1秒内扫描包裹信息&#xff1b;数字孪生平台正模拟次日峰值流量压力…...

OPENCV形态学基础之二腐蚀

一.腐蚀的原理 (图1) 数学表达式&#xff1a;dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一&#xff0c;腐蚀跟膨胀属于反向操作&#xff0c;膨胀是把图像图像变大&#xff0c;而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...