其中 Collection<String> 参数在几种分片策略中使用一致,在分库时值为所有分片库的集合 databaseNames,分表时为对应分片库中所有分片表的集合 tablesNames;PreciseShardingValue 为分片属性,其中 logicTableName 为逻辑表,columnName 分片健(字段),value 为从 SQL 中解析出的分片健的值。
而 application.properties 配置文件中只需修改分库策略名 database-strategy 为标准模式 standard,分片算法 standard.precise-algorithm-class-name 为自定义的精准分库算法类路径。
### 分库策略 # 分库分片健 spring.shardingsphere.sharding.tables.t_order.database-strategy.standard.sharding-column=order_id # 分库分片算法 spring.shardingsphere.sharding.tables.t_order.database-strategy.standard.precise-algorithm-class-name=com.xiaofu.sharding.algorithm.dbAlgorithm.MyDBPreciseShardingAlgorithm 1.2 精准分表算法精准分表算法同样实现 PreciseShardingAlgorithm 接口,并重写 doSharding() 方法。
/** * @author xiaofu 公众号【程序员内点事】 * @description 自定义标准分表策略 * @date 2020/10/30 13:48 */ public class MyTablePreciseShardingAlgorithm implements PreciseShardingAlgorithm<Long> { @Override public String doSharding(Collection<String> tableNames, PreciseShardingValue<Long> shardingValue) { /** * tableNames 对应分片库中所有分片表的集合 * shardingValue 为分片属性,其中 logicTableName 为逻辑表,columnName 分片健(字段),value 为从 SQL 中解析出的分片健的值 */ for (String tableName : tableNames) { /** * 取模算法,分片健 % 表数量 */ String value = shardingValue.getValue() % tableNames.size() + ""; if (tableName.endsWith(value)) { return tableName; } } throw new IllegalArgumentException(); } }分表时 Collection<String> 参数为上边计算出的分片库,对应的所有分片表的集合 tablesNames;PreciseShardingValue 为分片属性,其中 logicTableName 为逻辑表,columnName 分片健(字段),value 为从 SQL 中解析出的分片健的值。
application.properties 配置文件也只需修改分表策略名 database-strategy 为标准模式 standard,分片算法 standard.precise-algorithm-class-name 为自定义的精准分表算法类路径。
# 分表策略 # 分表分片健 spring.shardingsphere.sharding.tables.t_order.table-strategy.standard.sharding-column=order_id # 分表算法 spring.shardingsphere.sharding.tables.t_order.table-strategy.standard.precise-algorithm-class-name=com.xiaofu.sharding.algorithm.tableAlgorithm.MyTablePreciseShardingAlgorithm看到这不难发现,自定义分库和分表算法的实现基本是一样的,所以后边我们只演示分库即可
2、范围分片算法使用场景:当我们 SQL中的分片健字段用到 BETWEEN AND操作符会使用到此算法,会根据 SQL中给出的分片健值范围值处理分库、分表逻辑。
SELECT * FROM t_order where order_id BETWEEN 1 AND 100;自定义范围分片算法需实现 RangeShardingAlgorithm 接口,重写 doSharding() 方法,下边我通过遍历分片健值区间,计算每一个分库、分表逻辑。
/** * @author xinzhifu * @description 范围分库算法 * @date 2020/11/2 12:06 */ public class MyDBRangeShardingAlgorithm implements RangeShardingAlgorithm<Integer> { @Override public Collection<String> doSharding(Collection<String> databaseNames, RangeShardingValue<Integer> rangeShardingValue) { Set<String> result = new LinkedHashSet<>(); // between and 的起始值 int lower = rangeShardingValue.getValueRange().lowerEndpoint(); int upper = rangeShardingValue.getValueRange().upperEndpoint(); // 循环范围计算分库逻辑 for (int i = lower; i <= upper; i++) { for (String databaseName : databaseNames) { if (databaseName.endsWith(i % databaseNames.size() + "")) { result.add(databaseName); } } } return result; } }和上边的一样 Collection<String> 在分库、分表时分别代表分片库名和表名集合,RangeShardingValue 这里取值方式稍有不同, lowerEndpoint 表示起始值, upperEndpoint 表示截止值。
在配置上由于范围分片算法和精准分片算法,同在标准分片策略下使用,所以只需添加上 range-algorithm-class-name 自定义范围分片算法类路径即可。
# 精准分片算法 spring.shardingsphere.sharding.tables.t_order.database-strategy.standard.precise-algorithm-class-name=com.xiaofu.sharding.algorithm.dbAlgorithm.MyDBPreciseShardingAlgorithm # 范围分片算法 spring.shardingsphere.sharding.tables.t_order.database-strategy.standard.range-algorithm-class-name=com.xiaofu.sharding.algorithm.dbAlgorithm.MyDBRangeShardingAlgorithm 复合分片策略使用场景:SQL 语句中有>,>=, <=,<,=,IN 和 BETWEEN AND 等操作符,不同的是复合分片策略支持对多个分片健操作。
下面我们实现同时以 order_id、user_id 两个字段作为分片健,自定义复合分片策略。
SELECT * FROM t_order where user_id =0 and order_id = 1;