分库分表利器——shardingJdbc

news2025/7/13 16:46:22

一、分库分表方式

1.1 垂直切分

1.1.1 垂直分表(拆分字段——但每张表的数据量是不变的)

把一张表的一部分字段存在一张新表里面,将另一部分字段存在另一张新表中
在这里插入图片描述

1.1.2 垂直分库(专库专表)

把单一数据库按照业务拆分,专库专表,减少单一数据库压力
在这里插入图片描述

1.2 水平切分

1.2.1 水平分表

在原数据表的基础上复制几份结构相同的副本数据表,再根据特定的规则进行读取,进一步减少单表压力
在这里插入图片描述

1.2.2 水平分库

在原数据库的基础上复制几份结构相同的副本数据库,再根据特定的规则进行读取,进一步缓解单库压力
在这里插入图片描述

二、分库分表的应用和问题

2.1 应用

(1)在数据库设计时就要考虑垂直分库和垂直分表
(2)随着数据量的不断增加,不要马上考虑做水平切分,首先考虑缓存处理、读写分离、索引等方式,如果这些方式不能根本解决问题,再考虑做水平分库和分表

2.2 问题

(1)跨节点连接查询(当要连接查询时,需要去不同的数据库单独查出来再进行数据拼接汇总)
在这里插入图片描述

(2)多数据源管理问题

三、sharding-Jdbc(轻量的Java框架、JDBC的增强版)

它并不是做分库分表,而是对分库分表之后的数据表做相关操作,主要功能:数据分片、读写分离

3.1 水平分表

3.1.1 环境搭建

(1)创建一个数据库course_db及两张表,分别为course_1和course_2,两者表结构相同
在这里插入图片描述

(2)引入依赖

<!--  引入druid      -->
<dependency>
  <groupId>com.alibaba</groupId>
  <artifactId>druid-spring-boot-starter</artifactId>
  <version>1.2.11</version>
</dependency>
<!--  引入mybatis-plus      -->
<dependency>
  <groupId>com.baomidou</groupId>
  <artifactId>mybatis-plus-boot-starter</artifactId>
  <version>3.4.3.4</version>
</dependency>
<!--  mysql驱动      -->
<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <version>5.1.49</version>
</dependency>
<!--  sharding-JDBC      -->
<dependency>
  <groupId>org.apache.shardingsphere</groupId>
  <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
  <version>4.0.0-RC1</version>
</dependency>

(3)配置文件(官方文档)

# shardingjdbc 分片策略

# 配置数据源,给数据源起名称
spring.shardingsphere.datasource.names=db1

# 一个实体类对应多张表,覆盖
spring.main.allow-bean-definition-overriding=true

# 配置数据源具体内容,包含连接池,驱动,地址,用户名和密码
spring.shardingsphere.datasource.db1.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.db1.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.db1.url=jdbc:mysql://127.0.0.1:3306/course_db?useUnicode=true&&characterEncoding=utf-8&&useSSL=false
spring.shardingsphere.datasource.db1.username=root
spring.shardingsphere.datasource.db1.password=root

# 指定course表分布情况,配置表在哪个数据库里面,表名称都是什么 m1.course_1, m1.course_2
spring.shardingsphere.sharding.tables.course.actual-data-nodes=db1.course_$->{1..2}

# 指定course表的主键生成策略
spring.shardingsphere.sharding.tables.course.key-generator.column=cid
spring.shardingsphere.sharding.tables.course.key-generator.type=SNOWFLAKE

# 数据表分片策略 约定cid为偶数存course_1表, 为奇数存course_2表
spring.shardingsphere.sharding.tables.course.table-strategy.inline.sharding-column=cid
spring.shardingsphere.sharding.tables.course.table-strategy.inline.algorithm-expression=course_$->{cid % 2+1}

# 开启sql输出日志
spring.shardingsphere.props.sql.show=true

(4)插入数据测试

    @Test
    public void addCourse() {
    for (int i = 1; i < 10; i++) {
        Course course = new Course();
        course.setCname("Java "+i);
        course.setUserId(100L);
        course.setCstatus("Normal");
        courseMapper.insert(course);
    }
}

在这里插入图片描述
在这里插入图片描述
主键cid是偶数的全部分在了course_1表,奇数分在了course_2表
(5)查询测试

    @Test
    public void selectCourse() {
        QueryWrapper<Course> wrapper = new QueryWrapper<>();
        wrapper.eq("cid",770051025917706241L);
        System.out.println(courseMapper.selectOne(wrapper));
    }

在这里插入图片描述
770051025917706241是奇数,所以查询还是在course_2表

3.2 水平分库

3.2.1 环境搭建

(1)创建两个结构相同的数据库
在这里插入图片描述
数据库规则:
userid为偶数时添加到edu_db_1数据库,为奇数时添加到edu_db_2数据库
表规则:
cid为偶数时添加到course_1表,为奇数时添加到course_2表
在这里插入图片描述
(2)配置文件

# shardingjdbc 分片策略(水平分库)
# 配置数据源,给数据源起名称(对应两个数据库)
spring.shardingsphere.datasource.names=db1,db2

# 一个实体类对应多张表,覆盖
spring.main.allow-bean-definition-overriding=true

# 配置第一个数据源具体内容,包含连接池,驱动,地址,用户名和密码
spring.shardingsphere.datasource.db1.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.db1.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.db1.url=jdbc:mysql://127.0.0.1:3306/edu_db_1?useUnicode=true&&characterEncoding=utf-8&&useSSL=false
spring.shardingsphere.datasource.db1.username=root
spring.shardingsphere.datasource.db1.password=root

# 配置第二个数据源具体内容,包含连接池,驱动,地址,用户名和密码
spring.shardingsphere.datasource.db2.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.db2.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.db2.url=jdbc:mysql://127.0.0.1:3306/edu_db_2?useUnicode=true&&characterEncoding=utf-8&&useSSL=false
spring.shardingsphere.datasource.db2.username=root
spring.shardingsphere.datasource.db2.password=root

# 指定数据库分布情况,数据表分布情况
# db1 db2      course_1  course_2
spring.shardingsphere.sharding.tables.course.actual-data-nodes=db$->{1..2}.course_$->{1..2}
# 指定course表的主键生成策略
spring.shardingsphere.sharding.tables.course.key-generator.column=cid
spring.shardingsphere.sharding.tables.course.key-generator.type=SNOWFLAKE
# 指定数据库分片策略(默认的,也就是对全部表的user_id字段都生效)
#spring.shardingsphere.sharding.default-database-strategy.inline.sharding-column=user_id
#spring.shardingsphere.sharding.default-database-strategy.inline.algorithm-expression=edu_db_$->{user_id%2+1}
# 指定数据库分片策略(指定表的某些字段生效)
spring.shardingsphere.sharding.tables.course.database-strategy.inline.sharding-column=user_id
spring.shardingsphere.sharding.tables.course.database-strategy.inline.algorithm-expression=db$->{user_id % 2+1}
# 数据表分片策略 约定cid为偶数存course_1表, 为奇数存course_2表
spring.shardingsphere.sharding.tables.course.table-strategy.inline.sharding-column=cid
spring.shardingsphere.sharding.tables.course.table-strategy.inline.algorithm-expression=course_$->{cid % 2+1}
# 开启sql输出日志
spring.shardingsphere.props.sql.show=true

(3)测试

    @Test
    public void insertCourse() {
    for (int i = 1; i <= 10; i++) {
        Course course = new Course();
        //数据库(偶数在1 奇数在2)
        course.setUserId(11L);
        course.setCname("水平分库-" + i);
        course.setCstatus("Normal");
        courseMapper.insert(course);
    }
}

user_id为偶数存1号库,user_id为奇数存2号库;
cid为偶数存1号表,cid为奇数存2号表
在这里插入图片描述
在这里插入图片描述

3.3 垂直分库(专库专表)

3.3.1 环境搭建

(1)创建数据库
在上面水平分库的基础上再添加一个一个数据库user_db,并创建一张表t_user
在这里插入图片描述
(2)配置文件

# shardingjdbc 分片策略(垂直分库————专库专表)
# 配置数据源,给数据源起名称(对应两个数据库)
spring.shardingsphere.datasource.names=db1,db2,db3

# 一个实体类对应多张表,覆盖
spring.main.allow-bean-definition-overriding=true

# 配置第一个数据源具体内容,包含连接池,驱动,地址,用户名和密码
spring.shardingsphere.datasource.db1.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.db1.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.db1.url=jdbc:mysql://127.0.0.1:3306/edu_db_1?useUnicode=true&&characterEncoding=utf-8&&useSSL=false
spring.shardingsphere.datasource.db1.username=root
spring.shardingsphere.datasource.db1.password=root

# 配置第二个数据源具体内容,包含连接池,驱动,地址,用户名和密码
spring.shardingsphere.datasource.db2.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.db2.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.db2.url=jdbc:mysql://127.0.0.1:3306/edu_db_2?useUnicode=true&&characterEncoding=utf-8&&useSSL=false
spring.shardingsphere.datasource.db2.username=root
spring.shardingsphere.datasource.db2.password=root

# 配置第三个数据源具体内容,包含连接池,驱动,地址,用户名和密码
spring.shardingsphere.datasource.db3.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.db3.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.db3.url=jdbc:mysql://127.0.0.1:3306/user_db?useUnicode=true&&characterEncoding=utf-8&&useSSL=false
spring.shardingsphere.datasource.db3.username=root
spring.shardingsphere.datasource.db3.password=root

#--------------------------------------user_db数据库里面t_user 专库专表----------------------------------------------
# 配置user_db数据库里面t_user专库专表
spring.shardingsphere.sharding.tables.t_user.actual-data-nodes=db3.t_user

# 指定course表的主键生成策略
spring.shardingsphere.sharding.tables.t_user.key-generator.column=user_id
spring.shardingsphere.sharding.tables.t_user.key-generator.type=SNOWFLAKE

# 数据表分片策略 user表
spring.shardingsphere.sharding.tables.t_user.table-strategy.inline.sharding-column=user_id
spring.shardingsphere.sharding.tables.t_user.table-strategy.inline.algorithm-expression=t_user

#----------------------------------------edu_db_数据库里面course表 水平分库--------------------------------------------
# 配置edu_db_数据库里面course表的情况
spring.shardingsphere.sharding.tables.course.actual-data-nodes=db$->{1..2}.course_$->{1..2}

# 指定course表的主键生成策略
spring.shardingsphere.sharding.tables.course.key-generator.column=cid
spring.shardingsphere.sharding.tables.course.key-generator.type=SNOWFLAKE

# 数据表分片策略 约定cid为偶数存course_1表, 为奇数存course_2表
spring.shardingsphere.sharding.tables.course.table-strategy.inline.sharding-column=cid
spring.shardingsphere.sharding.tables.course.table-strategy.inline.algorithm-expression=course_$->{cid % 2+1}

# 指定数据库分片策略(默认的,也就是对全部表的user_id字段都生效)
#spring.shardingsphere.sharding.default-database-strategy.inline.sharding-column=user_id
#spring.shardingsphere.sharding.default-database-strategy.inline.algorithm-expression=edu_db_$->{user_id%2+1}

# 指定数据库分片策略(指定表的某些字段生效)
spring.shardingsphere.sharding.tables.course.database-strategy.inline.sharding-column=user_id
spring.shardingsphere.sharding.tables.course.database-strategy.inline.algorithm-expression=db$->{user_id % 2+1}

# 开启sql输出日志
spring.shardingsphere.props.sql.show=true

(3)测试

@Test
    public void addUser(){
    User user = new User();
    user.setUsername("lucy");
    user.setUstatus("Normal");
    userMapper.insert(user);
}

@Test
    public void findUser(){
    List<User> users = userMapper.selectList(null);
    System.out.println(users);
}

注意:数据表对应的实体类表名一定要和数据库表名相同(一定要能对应,否则可能会抛datasourse is null的异常)——最好指明数据库表名

四、Sharding-JDBC操作公共表

4.1 公共表

(1)存储固定数据的表,表数据很少发生变化,查询时经常进行关联
(2)在每个数据库中都有结构完全相同的表
实现操作公共表,也就是对每个数据库中的公共表同时进行添加、修改、删除操作
添加配置:

# 配置公共表
spring.shardingsphere.sharding.broadcast-tables=t_common
spring.shardingsphere.sharding.tables.t_common.key-generator.column=common_id
spring.shardingsphere.sharding.tables.t_common.key-generator.type=SNOWFLAKE

五、读写分离

5.1 概念

为了确保数据库的稳定性,大多拥有双机热备的功能,原理:主数据库(master)处理事务性增、删、改操作;从数据库(slave)处理select操作。
在这里插入图片描述

主从复制:当主服务器有写操作时,从服务器自动获取
原理:从服务器实时监控主服务器的binlog日志,当用户对主服务器进行写操作时改变了binlog日 志,从服务器拉取binlog日志读取并解析执行。从而实现与主数据库达到同步效果。

读写分离:写操作在主服务器,读操作在从服务器

5.2 mysql配置读写分离

(1)创建两个mysql数据库服务
直接复制之前mysql安装根目录,
在这里插入图片描述
修改配置(端口号、安装目录、数据存放目录),
在这里插入图片描述
为修改后的从数据库安装windows服务,mysqls1是服务名
cmd管理员权限:
注册服务

mysqld install mysqls1 --defaults-file=“D:\code\mysql-5.7.23-winx64-s1\my.ini”

删除服务

sc delete 服务名称
在这里插入图片描述
连接从数据库,
在这里插入图片描述
(2)配置mysql主从数据库
修改主数据库配置文件my.ini

[mysqld]
#开启日志
log-bin = mysql-bin
#设置服务id,主从不能一致
server-id = 1
#选择ROW模式
binlog_format=ROW
#设置需要同步的数据库
binlog-do-db=user_db
#屏蔽系统库同步
binlog-ignore-db=mysql
binlog-ignore-db=information_schema
binlog-ignore-db=performance_schema

修改从数据库配置文件my.ini

[mysqld]
#从服务器配置
#开启日志
log-bin=mysql-bin
#设置服务id,主从不能一致
server-id=2
#选择ROW模式
binlog_format=ROW
#设置需要同步的数据库
replicate_wild_do_table=user_db.%
#屏蔽系统库同步
replicate_wild_ignore_table=mysql.%
replicate_wild_ignore_table=information-schema.%
replicate_wild_ignore_table=performance_schema.%

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/17820.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一篇文章带你学完mysql的DQL查询操作

目录 DQL简介 具体操作 数据准备 简单查询 运算符 条件查询 排序查询 聚合查询 null值的处理 分组查询 分页查询 insert into select语句 总结 DQL简介 概念&#xff1a;DQL&#xff08;data query language&#xff09;数据查询语言 select操作 排序规则&…

关于Excel自动换行,不会在西文单词中间换行的问题

工作上遇到了一个Excel中换行的问题&#xff0c;就是使用了Excel的默认自动换行后&#xff0c;如果一个单词很长&#xff0c;那么一般情况下是不会在单词中间换行的。在网上查了些资料&#xff0c;最终找到了一个不算太完美的方法。 结果 就是使用vba修改单元格里面的内容&am…

SpringBoot SpringBoot 开发实用篇 4 数据层解决方案 4.11 SpringBoot 整合 MongoDB

SpringBoot 【黑马程序员SpringBoot2全套视频教程&#xff0c;springboot零基础到项目实战&#xff08;spring boot2完整版&#xff09;】 SpringBoot 开发实用篇 文章目录SpringBootSpringBoot 开发实用篇4 数据层解决方案4.11 SpringBoot 整合 MongoDB4.11.1 SpringBoot 整…

Redis 到底是单线程还是多线程呢?

前言 Redis是高性能分布式缓存常用中间件&#xff0c;我们经常说Redis是单线程的&#xff0c; 也有人说Redis在6.0版本采用了多线程&#xff0c;那么Redis到底是采用单线程呢&#xff1f;还是多线程&#xff1f; 通常说 Redis 是单线程&#xff0c;其实主要是指 Redis 对外提供…

CNCF基金会成员的分类

CNCF简介 2015年&#xff0c;谷歌与Linux基金会及众多行业合作伙伴一起建立了一个云原生计算基金会&#xff08;CNCF&#xff0c;Cloud Native Computing Foundation&#xff09;。CNCF旨在创建并推动一个新的计算范式&#xff0c;这个范式的目的是增强现代分布式系统&#xf…

dataset.py篇

dataset.py 目录&#xff1a; 前言观察数据书写代码函数解释 前言 在步骤中需要写自己的dataset类&#xff0c;并将label和image一一对应后返回。 观察数据 在书写dataset前最重要的就是要观察数据集&#xff0c;对数据集进行分析&#xff0c;比如了解图片大小&#xff0c…

maven基础入门

maven 1、maven简介 Apache Maven 是一个项目管理和构建工具&#xff0c;它基于项目对象模型(POM)的概念&#xff0c;通过一小段描述信息来管理项目的构建、报告和文档。官网 &#xff1a;http://maven.apache.org/什么是Maven&#xff1f;这里先引用知乎的一个回答 我先不说…

第五届“传智杯”全国大学生计算机大赛(练习赛) [传智杯 #5 练习赛] 复读

[传智杯 #5 练习赛] 复读 题目描述 给定若干个字符串&#xff0c;不定数量&#xff0c;每行一个。有些字符串可能出现了多次。如果读入一个字符串后&#xff0c;发现这个字符串以前被读入过&#xff0c;则这个字符串被称为前面相同的字符串的复读&#xff0c;这个字符串被称为…

Redis分布式锁剖析和几种客户端的实现

1. 背景 在传统的单体项目中&#xff0c;即部署到单个IIS上&#xff0c;针对并发问题&#xff0c;比如进销存中的出库和入库问题&#xff0c;多个人同时操作&#xff0c;属于一个IIS进程中多个线程并发操作的问题&#xff0c;这个时候可以引入线程锁lock/Monitor等&#xff0c;…

信息论随笔(三)交互信息量

之前讨论了一个事件的自信息量&#xff0c;但是实际情况下往往有多个事件发生&#xff0c;而且这些事件之间相互是有联系的。比如知道一个人踢足球&#xff0c;那么这个人很有可能会看世界杯。也就是说&#xff0c;我们可以通过一个事件获得另外一个事件的信息&#xff0c;或者…

解决Android Studio等开发软件出现更新TKK失败的两种方案

解决Android Studio等开发软件出现更新TKK失败的两种方案方案一 配置hosts1. 配置域名与IP2.扫描国内可用的IP方案二 替换翻译引擎百度翻译引擎在Android Studio等开发软件中利用Translation等翻译插件时&#xff0c;出现无法翻译的提示&#xff1a;更新TKK失败&#xff0c;请检…

数据结构之栈的实现及相关OJ题

&#x1f57a;作者启明星使 &#x1f383;专栏&#xff1a;《数据库》《C语言》 &#x1f3c7;分享一句话&#xff1a; 对的人会站在你的前途里 志同道合的人才看得懂同一片风景 大家一起加油&#x1f3c4;‍♂️&#x1f3c4;‍♂️&#x1f3c4;‍♂️ 希望得到大家的支持&am…

【毕业设计】新闻分类系统 - 深度学习 机器学习

文章目录0 前言1 简介2 参与及比较算法3 先说结论4 实现过程4.1 数据爬取4.2 数据预处理5 CNN文本分类6 最后0 前言 &#x1f525; Hi&#xff0c;大家好&#xff0c;这里是丹成学长的毕设系列文章&#xff01; &#x1f525; 对毕设有任何疑问都可以问学长哦! 这两年开始&a…

事件总线EventBus

事件总线是对发布-订阅模式的一种实现&#xff0c;是一种集中式事件处理机制&#xff0c;允许不同的组件之间进行彼此通信而又不需要相互依赖&#xff0c;达到一种解耦的目的。 什么是“总线”&#xff1a;一个集中式的事件处理机制。同时服务多个事件和多个观察者。相当于一个…

C#编程深入研究变量,类型和方法

编写正确的C#代码 简单的调试技术 变量的语法 声明类型和值 仅声明类型 访问修饰符 使用类型 通用内置类型 类型转换 推断式声明 自定义类型 类型综述 命名变量 变量的作用域 运算符 定义方法 指定参数 指定返回值 常见的Unity方法 Start方法 Update方法 …

金山云:基于 JuiceFS 的 Elasticsearch 温冷热数据管理实践

01 Elasticsearch 广泛使用带来的成本问题 Elasticsearch&#xff08;下文简称“ES”&#xff09;是一个分布式的搜索引擎&#xff0c;还可作为分布式数据库来使用&#xff0c;常用于日志处理、分析和搜索等场景&#xff1b;在运维排障层面&#xff0c;ES 组成的 ELK&#xff…

MMDetection3D库中的一些模块介绍

本文目前仅包含2个体素编码器、2个中间编码器、1个主干网络、1个颈部网络和1个检测头。如果有机会&#xff0c;会继续补充更多模型。 若发现内容有误&#xff0c;欢迎指出。 MMDetection3D的点云数据一般会经历如下步骤/模块&#xff1a; #mermaid-svg-q9Wy2NQvFHfuPWKs {font-…

骨传导原理是什么,佩戴骨传导耳机的过程中对于耳道有无损害

随着新时代的到来&#xff0c;我们周围的数码产品逐渐被新产物所替代&#xff0c;以往在耳机市面上&#xff0c;普遍都是入耳式耳机&#xff0c;但长时间佩戴这种耳机的话对于我们耳道来说是有着不可逆的伤害&#xff0c;而在近几年骨传导耳机的出现&#xff0c;打破了传统耳机…

18.Redis系列之AOF方式持久化

本文学习redis7两大持久化技术之一&#xff1a;AOF&#xff08;Append Only File&#xff09;日志追加方式持久化备份与还原&#xff0c;重写以及AOF方式的优缺点 1. AOF相关配置 首先我们先简单了解下Redis7中AOF相关配置 // 开启AOF方式持久化&#xff0c;默认no appendon…

基于真实场景解读 K8s Pod 的各种异常

在 K8s 中&#xff0c;Pod 作为工作负载的运行载体&#xff0c;是最为核心的一个资源对象。Pod 具有复杂的生命周期&#xff0c;在其生命周期的每一个阶段&#xff0c;可能发生多种不同的异常情况。K8s 作为一个复杂系统&#xff0c;异常诊断往往要求强大的知识和经验储备。结合…