数据库拆分5--使用sharding-jdbc来实现水平拆分

news2024/11/26 4:44:34

有三张表 user log order表,先将user log 和order垂直分库,然后将user表水平拆分

配置文件

spring.shardingsphere.enabled=true

spring.shardingsphere.datasource.names=wim-user,wim-order

spring.shardingsphere.datasource.wim-user.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.wim-user.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.wim-user.url=jdbc:mysql://127.0.0.1:3306/wim-user?serverTimezone=UTC&useSSL=false
spring.shardingsphere.datasource.wim-user.username=root
spring.shardingsphere.datasource.wim-user.password=123456

spring.shardingsphere.datasource.wim-order.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.wim-order.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.wim-order.url=jdbc:mysql://127.0.0.1:3306/wim-order?serverTimezone=UTC&useSSL=false
spring.shardingsphere.datasource.wim-order.username=root
spring.shardingsphere.datasource.wim-order.password=123456

spring.shardingsphere.sharding.tables.user_t.actual-data-nodes=wim-user.user_t_$->{0..1}
spring.shardingsphere.sharding.tables.log_t.actual-data-nodes=wim-user.log_t

spring.shardingsphere.sharding.tables.user_t.table-strategy.inline.sharding-column=user_id
spring.shardingsphere.sharding.tables.user_t.table-strategy.inline.algorithm-expression=user_t_$->{user_id % 2}

spring.shardingsphere.sharding.tables.log_t.table-strategy.inline.sharding-column=id
spring.shardingsphere.sharding.tables.log_t.table-strategy.inline.algorithm-expression=log_t


spring.shardingsphere.sharding.default-data-source-name=wim-order

spring.shardingsphere.props.sql.show=true

拆分的配置方法 直接看一下对应代码和实现类

学习一下各种分片策略:

行表达式分片策略(InlineShardingStrategy)

YamlInlineShardingStrategyConfiguration
public final class YamlInlineShardingStrategyConfiguration implements YamlBaseShardingStrategyConfiguration {
    private String shardingColumn;
    private String algorithmExpression;

    public YamlInlineShardingStrategyConfiguration() {
    }

    @Generated
    public String getShardingColumn() {
        return this.shardingColumn;
    }

    @Generated
    public String getAlgorithmExpression() {
        return this.algorithmExpression;
    }

    @Generated
    public void setShardingColumn(String shardingColumn) {
        this.shardingColumn = shardingColumn;
    }

    @Generated
    public void setAlgorithmExpression(String algorithmExpression) {
        this.algorithmExpression = algorithmExpression;
    }
}
spring.shardingsphere.sharding.tables.user_t.actual-data-nodes=wim-user.user_t_$->{0..1}
spring.shardingsphere.sharding.tables.user_t.table-strategy.inline.sharding-column=user_id
spring.shardingsphere.sharding.tables.user_t.table-strategy.inline.algorithm-expression=user_t_$->{user_id % 2}

需要配置分片键和分片表达式

有两张user表  user_t_0 user_t_1 根据user_id%2来路由到不同数据库。

1)使用场景:只支持单分片健;支持对 SQL语句中的 = 、IN 等的分片操作,不支持between and。

2)使用方法:适用于做简单的分片算法,在配置中使用 Groovy 表达式,无需自定义分片算法,省去了繁琐的代码开发,是几种分片策略中最为简单的。

标准分片策略(StandardShardingStrategy)

YamlStandardShardingStrategyConfiguration
public final class YamlStandardShardingStrategyConfiguration implements YamlBaseShardingStrategyConfiguration {
    private String shardingColumn;
    private String preciseAlgorithmClassName;
    private String rangeAlgorithmClassName;

SQL 语句中有>>=<=<=,IN和BETWEEN AND操作符,都可以应用此分片策略。它只支持对单个分片健(字段)为依据的分库分表,并提供了两种分片算法 PreciseShardingAlgorithm(精准分片)和 RangeShardingAlgorithm(范围分片)

精准分库算法:实现 PreciseShardingAlgorithm 接口,并重写 doSharding() 方法。其中 Collection<String> 参数在几种分片策略中使用一致,在分库时值为所有分片库的集合 databaseNames,分表时为对应分片库中所有分片表的集合 tablesNames;PreciseShardingValue 为分片属性,其中 logicTableName 为逻辑表,columnName 分片健(字段),value 为从 SQL 中解析出的分片健的值;

假设log表需要根据id来分片 大于1000的分片0  其他分片1

spring.shardingsphere.sharding.tables.log_t.actual-data-nodes=wim-user.log_t_$->{0..1}
spring.shardingsphere.sharding.tables.log_t.table-strategy.standard.sharding-column=id
spring.shardingsphere.sharding.tables.log_t.table-strategy.standard.precise-algorithm-class-name=com.chen.algorithm.MyPreciseShardingAlgorithm
public class MyPreciseShardingAlgorithm implements PreciseShardingAlgorithm {
	
	@Override
	public String doSharding(Collection collection, PreciseShardingValue preciseShardingValue) {
		Object[] ds = collection.toArray();
		long logId = (long) preciseShardingValue.getValue();
		if (logId > 1000) {
			return (String) ds[0];
		} else {
			return (String) ds[1];
		}
	}
}

在doSharding方法中可以实现更加复杂的判断逻辑

范围分片算法:分片健字段用到 BETWEEN AND操作符会使用到此算法,会根据 SQL中给出的分片健值范围值处理分库、分表逻辑。自定义范围分片算法需实现 RangeShardingAlgorithm 接口,重写 doSharding() 方法,Collection<String> 在分库、分表时分别代表分片库名和表名集合,RangeShardingValue 这里取值方式稍有不同, lowerEndpoint 表示起始值, upperEndpoint 表示截止值

假设log表 当查询时间范围包含2021年时 则从两个数据库查询合并结果返回 否则取第一个数据库数据返回

spring.shardingsphere.sharding.tables.log_t.actual-data-nodes=wim-user.log_t_$->{0..1}
spring.shardingsphere.sharding.tables.log_t.table-strategy.standard.sharding-column=log_date
spring.shardingsphere.sharding.tables.log_t.table-strategy.standard.range-algorithm-class-name=com.chen.algorithm.MyRangeShardingAlgorithm
spring.shardingsphere.sharding.tables.log_t.table-strategy.standard.precise-algorithm-class-name=com.chen.algorithm.MyPreciseShardingAlgorithm
public class MyRangeShardingAlgorithm implements RangeShardingAlgorithm<Date> {
	
	@Override
	public Collection<String> doSharding(Collection<String> collection, RangeShardingValue<Date> rangeShardingValue) {
		Range range = rangeShardingValue.getValueRange();
		boolean flag = range.contains("2021");
		if (flag) {
			return collection;
		} else {
			return Arrays.asList((String) collection.toArray()[0]);
		}
	}
}
RangeShardingAlgorithm算法需要和PreciseShardingAlgorithm一同实现来使用 否则算法加载会报错 好奇怪的逻辑
 if (null != yamlConfiguration.getStandard()) {
            ++shardingStrategyConfigCount;
            if (null == yamlConfiguration.getStandard().getRangeAlgorithmClassName()) {
                result = new StandardShardingStrategyConfiguration(yamlConfiguration.getStandard().getShardingColumn(), (PreciseShardingAlgorithm)ShardingAlgorithmFactory.newInstance(yamlConfiguration.getStandard().getPreciseAlgorithmClassName(), PreciseShardingAlgorithm.class));
            } else {
                result = new StandardShardingStrategyConfiguration(yamlConfiguration.getStandard().getShardingColumn(), (PreciseShardingAlgorithm)ShardingAlgorithmFactory.newInstance(yamlConfiguration.getStandard().getPreciseAlgorithmClassName(), PreciseShardingAlgorithm.class), (RangeShardingAlgorithm)ShardingAlgorithmFactory.newInstance(yamlConfiguration.getStandard().getRangeAlgorithmClassName(), RangeShardingAlgorithm.class));
            }
        }

复合分片策略

YamlComplexShardingStrategyConfiguration
public final class YamlComplexShardingStrategyConfiguration implements YamlBaseShardingStrategyConfiguration {
    private String shardingColumns;
    private String algorithmClassName;

SQL 语句中有>>=<=<=IN 和 BETWEEN AND 等操作符,且复合分片策略支持对多个分片健操作。自定义复合分片策略要实现 ComplexKeysShardingAlgorithm 接口,重新 doSharding()方法

假设log表 user_id log_date  userId=1 log_date包含2022的到表0中查询 其他两张表查询合并

spring.shardingsphere.sharding.tables.log_t.actual-data-nodes=wim-user.log_t_$->{0..1}
spring.shardingsphere.sharding.tables.log_t.table-strategy.complex.sharding-columns=user_id, log_date
spring.shardingsphere.sharding.tables.log_t.table-strategy.complex.algorithm-class-name=com.chen.algorithm.MyComplexKeysShardingAlgorithm
public class MyComplexKeysShardingAlgorithm implements ComplexKeysShardingAlgorithm {
	
	@Override
	public Collection<String> doSharding(Collection collection, ComplexKeysShardingValue complexKeysShardingValue) {
		System.out.println(complexKeysShardingValue);
		List<String> list = (List<String>) complexKeysShardingValue.getColumnNameAndShardingValuesMap().get("user_id");
		Range range = (Range) complexKeysShardingValue.getColumnNameAndRangeValuesMap().get("log_date");
		boolean flag1 = list.contains("1");
		boolean flag2 = range.contains("2022");
		if (flag1 && flag2) {
			return Arrays.asList((String) collection.toArray()[0]);
		}
		return collection;
	}
}

Hint分片策略

YamlHintShardingStrategyConfiguration
public final class YamlHintShardingStrategyConfiguration implements YamlBaseShardingStrategyConfiguration {
    private String algorithmClassName;

这种分片策略无需配置分片健,分片健值也不再从 SQL中解析,而是由外部指定分片信息,让 SQL在指定的分库、分表中执行。ShardingSphere 通过 Hint API实现指定操作,实际上就是把分片规则tablerule 、databaserule由集中配置变成了个性化配置。

实现 HintShardingAlgorithm 接口并重写 doSharding()方法

在请求的上下文中直接指定数据库和表

spring.shardingsphere.sharding.tables.log_t.actual-data-nodes=wim-user.log_t_$->{0..1}
spring.shardingsphere.sharding.tables.log_t.table-strategy.hint.algorithm-class-name=com.chen.algorithm.MyHintShardingAlgorithm
HintManager
@GetMapping("/query/{id}")
	public String query(@PathVariable Long id) {
		HintManager hintManager = HintManager.getInstance();
		hintManager.addTableShardingValue("log_t","1");
		Log logT = logMapper.selectById(id);
		log.info("query log {}", logT);
		if (logT == null) {
			return "cannot find user";
		}
		return logT.toString();
	}
public class MyHintShardingAlgorithm implements HintShardingAlgorithm {
	
	@Override
	public Collection<String> doSharding(Collection collection, HintShardingValue hintShardingValue) {
		Object[] ds = collection.toArray();
		Object[] v = hintShardingValue.getValues().toArray();
		int index = Integer.valueOf((String) v[0]);
		return Arrays.asList((String) ds[index]);
	}
}

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

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

相关文章

【JavaEE】多线程之Thread类

一、Thread类常见方法与字段 1、构造方法 构造方法说明Thread()不带参数的构造方法Thread(String name)可以在构造时传入线程的名字Thread(Runnable run)传入Runnable&#xff0c;是创建线程的方法之一Thread(Runnable run,String name)传入线程工作并给线程起名 2、常见属性…

JaveWeb框架(一):Web入门,Http的请求和响应,https介绍,Web实战自定义服务器

Servlet入门 MVC实战项目 仓储管理系统JavaWeb入门介绍Http协议Http请求数据格式Http响应数据格式Web实战Demo&#xff1a;自定义服务器对比Https协议总结Redis章节复习已经过去&#xff0c;新的章节JavaWeb开始了&#xff0c;这个章节中将会回顾JavaWeb实战项目 仓储管理 代码…

机器人开发--电机中的电流环、速度环、位置环

机器人开发--电机中的电流环、速度环、位置环电流环、速度环、位置环1 三环原理1.1 电流环1.2 速度环1.3 位置环2 各环与PID控制2.1 电流环重点在 PID&#xff08;比例、积分和微分&#xff09;2.2 速度环重点在 PI&#xff08;比例和积分&#xff09;2.3 位置环重点在 P&#…

基于JAVA的企业部门报销管理信息系统的设计与实现

开发工具(eclipse/idea/vscode等)&#xff1a; 数据库(sqlite/mysql/sqlserver等)&#xff1a; 功能模块(请用文字描述&#xff0c;至少200字)&#xff1a; 系统部分主要分为以下几个模块&#xff1a;公告类型&#xff0c;公告信息&#xff0c;部门信息&#xff0c;员工信 息&a…

手写Spring9(实现FactoryBean、对象作用域)

文章目录前言目标设计项目结构一、实现1、Bean的作用范围定义和xml解析2、创建和修改对象时候判断单例和原型模式3、定义 FactoryBean 接口4、实现一个 FactoryBean 注册服务5、扩展 AbstractBeanFactory 创建对象逻辑二、测试1、事先准备2、定义 FactoryBean 对象3、配置文件4…

Win32多线程调用gdal库接口

作者:朱金灿 来源:clever101的专栏 为什么大多数人学不会人工智能编程?>>> 效果图和程序说明 效果图如下:   这个程序是基于MFC的GUI程序,用于给指定的文件夹批量创建金字塔。   效果图如下:   这个程序是基于Win32 API的GUI程序,用于给指定的文件创…

期末前端web大作业——动漫客栈响应式bootstarp(7页) 排版整洁,内容丰富,主题鲜明

HTML实例网页代码, 本实例适合于初学HTML的同学。该实例里面有设置了css的样式设置&#xff0c;有div的样式格局&#xff0c;这个实例比较全面&#xff0c;有助于同学的学习,本文将介绍如何通过从头开始设计个人网站并将其转换为代码的过程来实践设计。 ⚽精彩专栏推荐&#x1…

R语言用线性回归模型预测空气质量臭氧数据

尽管线性模型是最简单的机器学习技术之一&#xff0c;但它们仍然是进行预测的强大工具。 最近我们被客户要求撰写关于线性回归模型的研究报告&#xff0c;包括一些图形和统计输出。 这尤其是由于线性模型特别容易解释这一事实。在这里&#xff0c;我将讨论使用空气质量数据集…

Python学习基础笔记五十四——多继承

多继承中&#xff0c;我们子类对象调用的一个方法&#xff0c;默认是就近原则&#xff0c;找的顺序是什么&#xff1f; 在经典类中&#xff0c;是深度优先&#xff1b; 在新式类中&#xff0c;是广度优先&#xff1b; Python2.7是经典类和新式类共存&#xff0c;新式类要继承…

领域模型设计模式

前言&#xff1a; 领域是一个组织所做的事情以及其包含的一切&#xff0c;通俗地说&#xff0c;就是组织的业务范围和做事情的方式&#xff0c;也是软件开发的目标范围。比如说淘宝的电商业务&#xff0c;C2C就是电子商务的领域&#xff0c;领域驱动设计就是从领域出发&#x…

安装VS code

五 安装VS Code Visual Studio Code&#xff0c;简称VS Code&#xff0c;是一种简化且高效的代码编辑器&#xff0c;同时支持诸如调试&#xff0c;任务执行和版本管理之类的开发操作。它的目标是提供一种快速的编码编译调试工具。优势&#xff1a; 支持多种语言的编写&#xf…

【大数据处理技术】「#1」本地数据集上传到数据仓库Hive

文章目录实验数据集下载下载实验数据集建立一个用于运行本案例的目录dbtaobao数据集的预处理删除文件第一行记录&#xff0c;即字段名称获取数据集中双11的前100000条数据导入数据仓库实验数据集下载 下载实验数据集 data_format.zip数据集用户行为日志user_log.csv&#xff…

jsp+ssm计算机毕业设计房屋租赁系统【附源码】

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; JSPSSM mybatis Maven等等组成&#xff0c;B/S模式 Mave…

node 使用 pm2 日志管理及使用 pm2-logrotate 进行日志分割

目录 1. 需求背景 2. 什么是 pm2-logrotate &#xff1f; 3. 查看 pm2 自带的日志管理 4. 安装 pm2-logrotate 5. 查看配置指令 6. pm2-logrotate 具体配置说明 7. 如何设置这些值&#xff1f; 8. 停止 pm2-logrotate 服务 9. 补充&#xff1a;pm2 常用命令 1. 需求…

Java学习笔记 --- MySQL-函数

一、合计/统计函数 count Count返回行的总数 SELECT COUNT(*) 列名 FROM table_name WHERE where_definition # 演示 mysql 的统计函数的使用 -- 统计一个班级共有多少学生&#xff1f; SELECT COUNT(*) FROM student -- 统计数学成绩大于90的学生有多少个 SELECT COUNT(*) FR…

Linux——vim的使用

实验5 vim的使用 一、两种模式&#xff1a; 命令行模式和编辑模式&#xff08;前者还有底行模式&#xff0c;命令行模式输入&#xff1a;就是底行模式&#xff09; 切换方法&#xff1a;进入vim后默认在命令模式&#xff0c;可以通过输入a后者i进入编辑模式&#xff0c;或者…

SQL学习day3

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 高级过滤Q1、检索供应商名称Q2、检索并列出已订购产品的清单(稍难&#xff09;Q3、返回所有价格在 3美元到 6美元之间的产品的名称和价格总结Q1、检索供应商名称 编写 SQL 语…

2022全年度吸尘器十大热门品牌销量榜单

近年来&#xff0c;随着社会经济的发展及人们生活水平的提升&#xff0c;吸尘器的市场需求得到不断地释放&#xff0c;行业规模也在不断扩大。但由于起步较晚&#xff0c;居民的消费能力尚未得到完全释放&#xff0c;目前我国吸尘器市场的渗透率还较低。 根据鲸参谋平台的数据统…

初识Go语言

Go是一种静态强类型、编译型、并发型语言。 一、Go语言的设计思维 尽可能少的方式去处理事情&#xff0c;减少选择的烦恼。 go的特点&#xff1a; 仅有25个关键字&#xff0c;简洁的语法内置垃圾回收器&#xff0c;大大降低程序员管理内存的负担去除隐式类型转换、去除指针…

UNIAPP实战项目笔记56 注册时验证手机号是否存在

UNIAPP实战项目笔记56 注册时验证手机号是否存在 注册时候需要拦截并验证登录 通过验证的直接跳转,未通过验证的提示手机号已存在 实际案例图片 后端接口文件 index.js var express require(express); var router express.Router(); var connection require(../db/sql.js);…