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

【经验分享】ShardingSphere+Springboot-04:自定义分片算法(COMPLEX/STANDARD)

文章目录

      • 3.4 CLASS_BASED 自定义类分片算法
        • 3.4.1 复杂分片自定义算法(strategy=COMPLEX )
        • 3.4.2 STANDARD 标准分片自定义算法
        • ## 进阶:star: 自定义算法+范围查询优化

3.4 CLASS_BASED 自定义类分片算法

3.4.1 复杂分片自定义算法(strategy=COMPLEX )

通过配置分片策略类型和算法类名,实现自定义扩展。 掌握自定义类算法就算法完全掌握了分片算法的精髓,可以根据业务需求灵活配置分片规则。

类型:CLASS_BASED

可配置属性:

属性名称数据类型说明
strategyString分片策略类型,支持 STANDARD、COMPLEX 或 HINT(不区分大小写)
algorithmClassNameString分片算法全限定名

官方文档给出了一个参考案例如下,没有太多的说明,这尝试用自定义分片算法重新实现[3.3.1]中的行表达式分表规则

package org.apache.shardingsphere.sharding.fixture;import org.apache.shardingsphere.sharding.api.sharding.standard.PreciseShardingValue;
import org.apache.shardingsphere.sharding.api.sharding.standard.RangeShardingValue;
import org.apache.shardingsphere.sharding.api.sharding.standard.StandardShardingAlgorithm;import java.util.Collection;public final class ClassBasedStandardShardingAlgorithmFixture implements StandardShardingAlgorithm<Integer> {@Override
public String doSharding(final Collection<String> availableTargetNames, final PreciseShardingValue<Integer> shardingValue) {for (String each : availableTargetNames) {if (each.endsWith(String.valueOf(shardingValue.getValue() % 4))) {return each;}}return null;
}@Override
public Collection<String> doSharding(final Collection<String> availableTargetNames, final RangeShardingValue<Integer> shardingValue) {return availableTargetNames;
}
}

实现目标:根据用户类型user_type和部门dep_id进行复杂分库分表

编写分片算法类:

  1. 根据分片策略类型( STANDARD、COMPLEX 或 HINT)实现对应的算法接口,这里需要用到的复杂算法的接口

    image-20240809111027491

  2. 实现必须的方法,这里核心关注doSharding方法,编写思路记录如下

    • 获取列名和分片值的映射(必备的,获取了才能根据分片键值计算数据源嘛
    • (可选)获取逻辑表名、范围值映射
    • 获取分片键值,并计算得到真实数据源

完整算法类:

package com.zhc.shard.algo;import lombok.extern.slf4j.Slf4j;
import org.apache.shardingsphere.sharding.api.sharding.complex.ComplexKeysShardingAlgorithm;
import org.apache.shardingsphere.sharding.api.sharding.complex.ComplexKeysShardingValue;import java.util.*;/*** @Author zhuhuacong* @Date: 2024/08/09/ 11:07* @description*/
@Slf4j
public class UserTypeDepIdAlgorithm implements ComplexKeysShardingAlgorithm<String> {// 定义列名常量private static final String col1 = "user_type";private static final String col2 = "dep_id";/*** 实现分片逻辑* 当分片条件存在时,根据给定的分片键计算出特定的数据源* 如果无法计算出合适的分片结果,则抛出异常** @param collection               数据源集合(这里是分表策略,所以这里是真实表集合* @param complexKeysShardingValue 分片条件对象* @return 分片后的数据源名称列表* @throws RuntimeException 当无法得到合适的分片结果时*/@Overridepublic Collection<String> doSharding(Collection collection, ComplexKeysShardingValue complexKeysShardingValue) {// 获取逻辑表名String logicTableName = complexKeysShardingValue.getLogicTableName();// 获取列名和分片值的映射Map columnNameAndShardingValuesMap = complexKeysShardingValue.getColumnNameAndShardingValuesMap();// 获取列名和范围值的映射(未用到)Map columnNameAndRangeValuesMap = complexKeysShardingValue.getColumnNameAndRangeValuesMap();// 获取分片键值List c1UserType = (List) columnNameAndShardingValuesMap.get(col1);List c2DepId = (List) columnNameAndShardingValuesMap.get(col2);// 如果任一分片键存在,则进行分片计算if (Optional.ofNullable(c1UserType).isPresent() || Optional.ofNullable(c2DepId).isPresent()) {// 【算法核心】 根据分片键值计算数据源索引long userType = c1UserType.get(0) != null ? Long.parseLong(c1UserType.get(0).toString()) : 0;long depId = c2DepId.get(0) != null ? Long.parseLong(c2DepId.get(0).toString()) : 0;long shardingId = ((userType + depId) % 2);String tableName = logicTableName + "_" + shardingId;log.info("userType:{};shardingId:{};余数{};真是表名{}", userType, depId, shardingId , tableName);// 返回计算后的数据源名称return Collections.singletonList(tableName);}// 如果无法得到合适的分片结果,则记录日志并抛出异常log.info("没有得到合适的分片结果=:表名{},参数:{}", collection, columnNameAndShardingValuesMap);throw new RuntimeException("没有得到合适的分片结果");}@Overridepublic Properties getProps() {return null;}@Overridepublic void init(Properties properties) {}
}

进行测试

分表策略运行正确

image-20240809114449222

3.4.2 STANDARD 标准分片自定义算法

快速实现,表结构还是参考前面的打卡表。要求根据早中晚三个时段的打卡时间进行分表,分别存入

stu_clock_am、stu_clock_noon、stu_clock_eve;

yaml配置如下

spring:shardingsphere:rules:sharding:tables:# 打卡表stu_clock:actual-data-nodes: dsmain.stu_clock_am,dsmain.stu_clock_noon,dsmain.stu_clock_evekey-generate-strategy:column: idkey-generator-name: snowflaketable-strategy:standard:sharding-column: clockin_timesharding-algorithm-name: stu_clock_class_algo# 配置分片算法sharding-algorithms:stu_clock_class_algo:type: CLASS_BASEDprops:#分片策略类型,支持 STANDARD、COMPLEX 或 HINT(不区分大小写)strategy: STANDARD# 分片算法全限定名algorithmClassName: com.zhc.shard.algo.StuClockClassAlgorithm

算法代码

package com.zhc.shard.algo;import cn.hutool.core.date.DateUtil;
import com.google.common.collect.Range;
import lombok.extern.slf4j.Slf4j;
import org.apache.shardingsphere.sharding.api.sharding.standard.PreciseShardingValue;
import org.apache.shardingsphere.sharding.api.sharding.standard.RangeShardingValue;
import org.apache.shardingsphere.sharding.api.sharding.standard.StandardShardingAlgorithm;import java.time.LocalDateTime;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Properties;/*** @Author zhuhuacong* @Date: 2024/08/09/ 14:56* @description StuClockClassAlgorithm*/
@Slf4j
public class StuClockClassAlgorithm implements StandardShardingAlgorithm<Date> {@Overridepublic String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Date> shardingValue) {String logicTableName = shardingValue.getLogicTableName();Date date = shardingValue.getValue();LocalDateTime localDateTime = DateUtil.toLocalDateTime(date);int hour = localDateTime.getHour();log.info("logicTableName: {} value: {} hour {}", logicTableName, date, hour);String actualTableName =null;if (hour > 15){actualTableName =  logicTableName + "_eve";} else if (hour > 10 ){actualTableName =  logicTableName + "_noon";} else {actualTableName =  logicTableName + "_am";}if (availableTargetNames.contains(actualTableName)){return actualTableName;}// 如果无法得到合适的分片结果,则记录日志并抛出异常log.info("没有得到合适的分片结果:表名{},参数:{}", shardingValue, shardingValue);throw new RuntimeException("没有得到合适的分片结果");}@Overridepublic Collection<String> doSharding(Collection<String> availableTargetNames, RangeShardingValue<Date> shardingValue) {return availableTargetNames;}@Overridepublic Properties getProps() {return null;}@Overridepublic void init(Properties properties) {}
}

结果测试,

生成随机打卡时间,观察是否正确入库

image-20240809153044358

结果符合预期

## 进阶⭐️ 自定义算法+范围查询优化

可以发现,StandardShardingAlgorithm接口还有一个同样叫doSharding的接口,

    /*** Sharding.** @param availableTargetNames available data sources or table names* @param shardingValue sharding value* @return sharding results for data sources or table names*/Collection<String> doSharding(Collection<String> availableTargetNames, RangeShardingValue<T> shardingValue);

传入的参数是一个带有范围(上下界限)shardingValue,一个是可用的真实表集合availableTargetNames,返回参数就是需要查询的目标表列表。

只要根据实际业务逻辑实现方法体内容即可。

相关文章:

【经验分享】ShardingSphere+Springboot-04:自定义分片算法(COMPLEX/STANDARD)

文章目录 3.4 CLASS_BASED 自定义类分片算法3.4.1 复杂分片自定义算法&#xff08;strategyCOMPLEX &#xff09;3.4.2 STANDARD 标准分片自定义算法## 进阶:star: 自定义算法范围查询优化 3.4 CLASS_BASED 自定义类分片算法 3.4.1 复杂分片自定义算法&#xff08;strategyCOM…...

如何设置RabbitMQ和Redis消息队列系统

设置RabbitMQ和Redis作为消息队列系统时&#xff0c;需要分别进行安装、配置和测试&#xff0c;以确保它们能够正常工作并满足你的应用需求。以下是一个基于这两个系统的设置指南&#xff1a; RabbitMQ的设置 1. 安装Erlang 由于RabbitMQ是用Erlang语言编写的&#xff0c;因…...

白骑士的Matlab教学高级篇 3.3 工具箱与扩展

MATLAB 提供了丰富的工具箱&#xff08;Toolbox&#xff09;和扩展功能&#xff0c;这些工具箱涵盖了各个领域的专业计算需求&#xff0c;如信号处理、图像处理、统计与机器学习等。利用工具箱&#xff0c;用户可以快速实现复杂的计算和分析任务。本文将介绍常用的工具箱及其使…...

bug: 配置flyway.locations多个脚本位置不生效

文章目录 业务场景场景一场景二 业务场景 随着项目版本迭代&#xff0c;数据库结构也会变动。如果一个项目引用其他项目的jar包&#xff0c;并且需要执行对应jar包的flyway脚本&#xff0c;就需要配置flyway.locations 场景一 正常情况下&#xff0c;在一个项目中可以在yml文件…...

8月5日SpringBoot学习笔记

今日内容:搭建mybatis ORM 配置数据源 $#的区别 增删改查 搭建mybatis 在原有maven项目基础配置上进行&#xff1a; pom文件添加依赖 <!-- Mybatis --><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-…...

Java学习笔记(二十):反射、动态代理、日志、类加载器、xml、单元测试Junit、注解

目录 一、反射 1.1 反射的概述&#xff1a; 1.2 学习反射到底学什么&#xff1f; 1.3 获取字节码文件对象的三种方式 1.4 字节码文件和字节码文件对象 1.5 获取构造方法 1.6 获取构造方法并创建对象 1.7 获取成员变量 1.8 获取成员变量并获取值和修改值 1.9 获取成员…...

如何快速从文本中找到需要的信息,字典和正则灵活运用

import re #打开文本文件 f open("stock_data.txt",encoding"utf-8") #单独读取第一行数据处理进行分割&#xff0c;末尾换行符去掉 headers f.readline().strip().split(,) print(headers) #定义一个字典&#xff0c;以股标代码做为KEY,每个行做为值 st…...

springboot3整合redis

来源于https://www.bilibili.com/video/BV1UC41187PR/?spm_id_from333.1007.top_right_bar_window_history.content.click&vd_source865f32e12aef524afb83863069b036aa 一、整合redis 1.创建项目文件 2.添加依赖 <dependencies><dependency><groupId>…...

VUE基础快速入门

VUE 和 VUE-Cli VUE 是一种流行的渐进式JavaScript框架&#xff0c;用于构建Web用户界面它具有易学、轻量级、灵活性强、高效率等特点&#xff0c;并且可以与其他库和项目集成是目前最流行的前端框架之一VUE-Cli 称为“VUE脚手架”,它是由VUE官方提供的客户端&#xff0c;专门为…...

用Python实现特征工程之特征提取——数值特征提取、类别特征提取、文本特征提取、时间特征提取

特征提取是特征工程中的关键步骤&#xff0c;它从原始数据中提取有意义的特征&#xff0c;以便机器学习模型能够更好地理解和学习数据。根据数据类型&#xff0c;特征提取可以分为数值特征提取、类别特征提取、文本特征提取和时间特征提取。下面详细讲解每种特征提取方法&#…...

按图搜索新体验:阿里巴巴拍立淘API返回值详解

阿里巴巴拍立淘API是一项基于图片搜索的商品搜索服务&#xff0c;它允许用户通过上传商品图片&#xff0c;系统自动识别图片中的商品信息&#xff0c;并返回与之相关的搜索结果。以下是对阿里巴巴拍立淘API返回值的详细解析&#xff1a; 一、主要返回值内容 商品信息 商品列表…...

vue跨域问题

本地调试 可以通过在vue.config.js中配置devServer来实现跨域请求。 module.exports {publicPath: ./,productionSourceMap: false, // 生产环境是否生成 sourceMap 文件devServer: {proxy: {/bi: {target: http://1.11.113.20:1234/bi, // 后台接口域名ws: false, //…...

【NLP】文本处理的基本方法【jieba分词、命名实体、词性标注】

文章目录 1、本章目标2、什么是分词3、jieba的使用3.1、精确模式分词3.2、全模式分词3.3、搜索引擎模式分词3.4、中文繁体分词3.5、使用用户自定义词典 4、什么是命名实体识别5、什么是词性标注6、小结7、jieba词性对照表⭐ &#x1f343;作者介绍&#xff1a;双非本科大三网络…...

unity 本地使用Json(全套)

提示&#xff1a;文章有错误的地方&#xff0c;还望诸位大神不吝指教&#xff01; 文章目录 前言一、Json是什么&#xff1f;二、创建Json文件1.在线编辑并转实体类&#xff08;C#&#xff09;2.Json文件 三、解析Json并使用四、报错&#xff1a;JsonError&#xff1a;JsonExce…...

java消息队列ActiveMQ

安装 前置条件 activemq的运行依赖于jdk&#xff0c;需要提前安装jdk如果已经安装了jdk&#xff0c;需要根据jdk的版本来选择对应的版本进行安装activemq版本对应在官网上&#xff0c;使用java -version 看jdk的版本注意&#xff1a;jdk和mq的版本不一致会报错&#xff0c;电脑…...

Android SurfaceFlinger——信号同步原理(五十一)

经过前面系列文章的学习,我们的已经理解了 SurfaceFlinger 运行机制以及同步机制,但是SurfaceFlinger 又是以什么方法是把需要刷新的信号发送给 App 进程的。 一、VSync简介 垂直同步(Vertical Synchronization,简称 VSync)是一种用于同步视频信号和显示设备刷新率的技术…...

html+css网页制作 博云丝网5个页面 无js ui还原度100%

htmlcss网页制作 博云丝网5个页面 无js ui还原度100% 网页作品代码简单&#xff0c;可使用任意HTML编辑软件&#xff08;如&#xff1a;Dreamweaver、HBuilder、Vscode 、Sublime 、Webstorm、Text 、Notepad 等任意html编辑软件进行运行及修改编辑等操作&#xff09;。 获取…...

Docker Hub 镜像代理加速

因为未知原因&#xff0c;docker hub 已经不能正常拉取镜像&#xff0c;可以使用以下代理服务来进行&#xff1a; "https://docker.m.daocloud.io", "https://noohub.ru", "https://huecker.io", "https://dockerhub.timeweb.cloud"…...

矩阵:消除冗余

矩阵 基本概念 矩阵&#xff08;Matrix&#xff09;是一个按照行和列排列的元素的二维数组。具体来说&#xff0c;一个 ( m \times n ) 的矩阵有 ( m ) 行和 ( n ) 列&#xff0c;表示为&#xff1a; A ( a 11 a 12 ⋯ a 1 n a 21 a 22 ⋯ a 2 n ⋮ ⋮ ⋱ ⋮ a m 1 a m 2 ⋯…...

【AWS账号解绑关联】Linker账号解绑重新关联注意事项

文章目录 一、来自客户疑问二、提交工单获取帮助三、最佳操作说明四、最佳操作步骤五、参考资料活动上新 一、来自客户疑问 将Linker账号&#xff0c;从一个组织中退出&#xff0c;重新关联到新的组织中&#xff0c;这解绑到重新完成新的关联绑定期间会在Linker账号中的账单中…...

YOLO X Layout部署教程:CentOS 7离线环境安装ONNX Runtime 1.16兼容包

YOLO X Layout部署教程&#xff1a;CentOS 7离线环境安装ONNX Runtime 1.16兼容包 1. 引言 如果你正在CentOS 7服务器上部署YOLO X Layout文档理解模型&#xff0c;可能会遇到一个常见问题&#xff1a;系统自带的ONNX Runtime版本太旧&#xff0c;而YOLO X Layout需要1.16或更…...

彻底解决Windows磁盘空间危机:Driver Store Explorer专业驱动管理指南

彻底解决Windows磁盘空间危机&#xff1a;Driver Store Explorer专业驱动管理指南 【免费下载链接】DriverStoreExplorer Driver Store Explorer 项目地址: https://gitcode.com/gh_mirrors/dr/DriverStoreExplorer 你是否曾为Windows系统盘空间不断缩小而烦恼&#xff…...

自动控制原理实验四:基于MATLAB/Simulink的系统频率特性分析与可视化

1. 实验背景与核心概念 频率特性分析是自动控制领域最实用的工具之一&#xff0c;它就像给系统做"心电图"——通过不同频率的输入信号&#xff0c;观察系统的"心跳反应"。我在工业现场调试时&#xff0c;经常用这种方法快速判断系统稳定性。这次我们要用M…...

JetBrains IDE试用期管理完全指南:从技术原理到合规使用

JetBrains IDE试用期管理完全指南&#xff1a;从技术原理到合规使用 【免费下载链接】ide-eval-resetter 项目地址: https://gitcode.com/gh_mirrors/id/ide-eval-resetter 一、问题导入&#xff1a;当试用期结束打断开发流程时 1.1 开发中断的典型场景 想象这样一个…...

保姆级教程:用llama.cpp把魔塔社区的safetensors模型转成Ollama能用的GGUF格式

从魔塔社区到Ollama&#xff1a;零基础完成safetensors到GGUF的华丽转身 刚接触开源大模型的新手们&#xff0c;往往会在魔塔社区发现令人心动的模型——比如最近热门的DeepSeek-R1系列。但下载后却面临一个尴尬局面&#xff1a;这些模型通常是safetensors格式&#xff0c;而Ol…...

LAV Filters专业配置进阶指南:深度解析开源解码器架构与性能优化

LAV Filters专业配置进阶指南&#xff1a;深度解析开源解码器架构与性能优化 【免费下载链接】LAVFilters LAV Filters - Open-Source DirectShow Media Splitter and Decoders 项目地址: https://gitcode.com/gh_mirrors/la/LAVFilters LAV Filters是一套基于FFmpeg的高…...

VideoAgentTrek-ScreenFilter效果展示:远程桌面RDP协议画面中窗口标题栏识别

VideoAgentTrek-ScreenFilter效果展示&#xff1a;远程桌面RDP协议画面中窗口标题栏识别 你有没有遇到过这样的场景&#xff1f;在观看远程桌面录屏或视频会议录像时&#xff0c;屏幕上密密麻麻的窗口标题栏、任务栏、系统托盘图标&#xff0c;让人眼花缭乱。特别是当需要分析…...

Wan2.2-I2V-A14B多场景应用:文旅宣传/电商主图/社交媒体动态生成

Wan2.2-I2V-A14B多场景应用&#xff1a;文旅宣传/电商主图/社交媒体动态生成 1. 开箱即用的视频创作利器 想象一下&#xff0c;你只需要输入一段文字描述&#xff0c;就能自动生成一段高清视频。这就是Wan2.2-I2V-A14B文生视频模型带来的革命性体验。无论你是文旅行业的宣传人…...

单片机通信协议详解:IIC、SPI、UART与CAN对比

1. 单片机通信协议概述在嵌入式系统开发中&#xff0c;单片机的通信能力直接影响着整个系统的架构设计和性能表现。作为一名有着十年嵌入式开发经验的工程师&#xff0c;我经常需要根据项目需求选择合适的通信协议。目前主流的单片机通信方式包括IIC、SPI、UART/USART、CAN等&a…...

OpenClaw+Qwen3.5-9B:法律文档审查助手实战

OpenClawQwen3.5-9B&#xff1a;法律文档审查助手实战 1. 为什么需要AI法律文档助手&#xff1f; 去年接手一个跨境合作项目时&#xff0c;我曾在72小时内手动审阅了137页的英文合同草案。那段经历让我意识到&#xff1a;传统人工审查不仅效率低下&#xff0c;还容易因疲劳遗…...