inline 配置,只支持 = IN 两种 SQL 语法
但是业务需要 >= <= 之类的范围查询,所以需要修改分片策略
- 实现精准分片接口 PreciseShardingAlgorithm 和范围分片接口 RangeShardingAlgorithm
- 修改 application.yaml 配置文件
配置文件:
...省略数据源以及默认配置...t_eth_transaction:actual-data-nodes: test$->{1}.t_eth_transaction$->{9..12}table-strategy:# inline:# sharding-column: block_number# algorithm-expression: t_eth_transaction$->{ (block_number/1000000) as int} # 分表规则为id对3取模,id%3为0表示分到user0表standard: # 单列sharidng算法,需要配合对应的 preciseShardingAlgorithm,rangeShardingAlgorithm 接口的实现使用shardingColumn: block_number # 列名,允许单列preciseAlgorithmClassName: com.paradise.sharding.strategy.RangeShardingAlgorithmImpl # preciseShardingAlgorithm接口的实现类rangeAlgorithmClassName: com.paradise.sharding.strategy.RangeShardingAlgorithmImpl # rangeShardingAlgorithm接口的实现类
接口实现:
package com.paradise.sharding.strategy;import com.google.common.collect.Range;import lombok.extern.slf4j.Slf4j;import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;import org.apache.shardingsphere.api.sharding.standard.PreciseShardingValue;import org.apache.shardingsphere.api.sharding.standard.RangeShardingAlgorithm;import org.apache.shardingsphere.api.sharding.standard.RangeShardingValue;import java.util.Collection;import java.util.LinkedHashSet;import java.util.Map;import java.util.function.Function;import java.util.stream.Collectors;/*** 分片策略实现* 包含精准分片与范围分片** @author Paradise*/@Slf4jpublic class RangeShardingAlgorithmImpl implements RangeShardingAlgorithm<Long>, PreciseShardingAlgorithm<Long> {/*** 100w 分片区块*/private static final long DIVISOR = 1_000_000;/*** 分片表前缀*/private static final String TABLE_PREFIX = "t_eth_transaction";public RangeShardingAlgorithmImpl() {log.info("初始化 -> [{}]", "RangeShardingAlgorithmImpl ----- 范围分片算法-启用");}/*** Sharding.** @param availableTargetNames available data sources or tables' names* @param shardingValue sharding value* @return sharding results for data sources or tables' names*/@Overridepublic Collection<String> doSharding(Collection<String> availableTargetNames, RangeShardingValue<Long> shardingValue) {// 可用表名称 Mapfinal Map<String, String> map = availableTargetNames.stream().collect(Collectors.toMap(Function.identity(), Function.identity()));// 构造返回结果Collection<String> result = new LinkedHashSet<>(availableTargetNames.size());// 获取待查询范围Range<Long> range = shardingValue.getValueRange();// 除法取整long low = range.lowerEndpoint() / DIVISOR;long upper = range.upperEndpoint() / DIVISOR;// 遍历获取路由表信息for (long i = low; i <= upper; i++) {final String table = TABLE_PREFIX + i;if (map.containsKey(table)) {result.add(table);}}return result;}/*** Sharding.** @param availableTargetNames available data sources or tables' names* @param shardingValue sharding value* @return sharding result for data source or table's name*/@Overridepublic String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Long> shardingValue) {// 可用表名称 Mapfinal Map<String, String> map = availableTargetNames.stream().collect(Collectors.toMap(Function.identity(), Function.identity()));final long value = shardingValue.getValue() / DIVISOR;final String table = TABLE_PREFIX + value;if (map.containsKey(table)) {return table;}log.info("分片表:{} 不存在", table);throw new UnsupportedOperationException(table + " Not Exist!");}}
