wordpress 新建主题,seo查询官方网站,网站使用什么数据库,百度指数怎么刷指数方法文章目录 3.4 CLASS_BASED 自定义类分片算法3.4.1 复杂分片自定义算法#xff08;strategyCOMPLEX #xff09;3.4.2 STANDARD 标准分片自定义算法## 进阶:star: 自定义算法范围查询优化 3.4 CLASS_BASED 自定义类分片算法
3.4.1 复杂分片自定义算法#xff08;strategyCOM… 文章目录 3.4 CLASS_BASED 自定义类分片算法3.4.1 复杂分片自定义算法strategyCOMPLEX 3.4.2 STANDARD 标准分片自定义算法## 进阶:star: 自定义算法范围查询优化 3.4 CLASS_BASED 自定义类分片算法
3.4.1 复杂分片自定义算法strategyCOMPLEX
通过配置分片策略类型和算法类名实现自定义扩展。 掌握自定义类算法就算法完全掌握了分片算法的精髓可以根据业务需求灵活配置分片规则。
类型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 StandardShardingAlgorithmInteger {Override
public String doSharding(final CollectionString availableTargetNames, final PreciseShardingValueInteger shardingValue) {for (String each : availableTargetNames) {if (each.endsWith(String.valueOf(shardingValue.getValue() % 4))) {return each;}}return null;
}Override
public CollectionString doSharding(final CollectionString availableTargetNames, final RangeShardingValueInteger shardingValue) {return availableTargetNames;
}
}实现目标根据用户类型user_type和部门dep_id进行复杂分库分表
编写分片算法类 根据分片策略类型 STANDARD、COMPLEX 或 HINT实现对应的算法接口这里需要用到的复杂算法的接口 实现必须的方法这里核心关注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 ComplexKeysShardingAlgorithmString {// 定义列名常量private static final String col1 user_type;private static final String col2 dep_id;/*** 实现分片逻辑* 当分片条件存在时根据给定的分片键计算出特定的数据源* 如果无法计算出合适的分片结果则抛出异常** param collection 数据源集合(这里是分表策略所以这里是真实表集合* param complexKeysShardingValue 分片条件对象* return 分片后的数据源名称列表* throws RuntimeException 当无法得到合适的分片结果时*/Overridepublic CollectionString 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) {}
}
进行测试
分表策略运行正确 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 StandardShardingAlgorithmDate {Overridepublic String doSharding(CollectionString availableTargetNames, PreciseShardingValueDate 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 CollectionString doSharding(CollectionString availableTargetNames, RangeShardingValueDate shardingValue) {return availableTargetNames;}Overridepublic Properties getProps() {return null;}Overridepublic void init(Properties properties) {}
}结果测试
生成随机打卡时间观察是否正确入库 结果符合预期
## 进阶⭐️ 自定义算法范围查询优化
可以发现StandardShardingAlgorithm接口还有一个同样叫doSharding的接口 /*** Sharding.** param availableTargetNames available data sources or table names* param shardingValue sharding value* return sharding results for data sources or table names*/CollectionString doSharding(CollectionString availableTargetNames, RangeShardingValueT shardingValue);传入的参数是一个带有范围(上下界限)shardingValue一个是可用的真实表集合availableTargetNames返回参数就是需要查询的目标表列表。
只要根据实际业务逻辑实现方法体内容即可。