当前位置:   article > 正文

数据库分库分表(三)shardingjdbc分片策略_分表策略preciseshardingalgorithm

分表策略preciseshardingalgorithm

介绍:

1)分片维度:数据源分片策略、表分片策略,即分库跟分表;

2)分片键:用于分片的数据库字段,是将数据库(表)水平拆分的关键字段。SQL中如果无分片字段,将执行全路由(全库、全表逐一执行),性能较差。 除了对单分片字段的支持,ShardingSphere也支持根据多个字段进行分片;

3)分片算法:PreciseShardingAlgorithm、RangeShardingAlgorithm、HintShardingAlgorithm、

ComplexKeysShardingAlgorithm。

分片策略由分片键和分片算法组成。注意:以下SQL会执行全路由,在分片维度的分布范围,即在各个表(库)都执行一次,最后自动汇总并返回结果:

  • 聚合函数
  • >=、<=
  • 分页查询,order  by...limit... 
  • 以上之外,where条件中无该(库或表)分片键

一、行表达式分片策略(InlineShardingStrategy):

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

(2)使用方法:适用于做简单的分片算法,在配置中使用 Groovy 表达式,无需自定义分片算法,省去了繁琐的代码开发,是几种分片策略中最为简单的。利用inline.algorithm-expression书写表达式,如ds-$->{order_id % 2} 表示对 order_id 做取模计算,$ 是个通配符用来承接取模结果,最终计算出分库ds-0 ··· ds-n

  1. # 行表达式分片键
  2. sharding.jdbc.config.sharding.tables.t_order.database-strategy.inline.sharding-column=order_id
  3. # 表达式算法
  4. sharding.jdbc.config.sharding.tables.t_order.database-strategy.inline.algorithm-expression=ds-$->{order_id % 2}

二、标准分片策略(StandardShardingStrategy):

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

(2)使用方法:使用标准分片策略时,精准分片算法是必须实现的算法,用于 SQL 含有 = 和 IN等 的分片处理;范围分片算法是非必选的,用于处理含有 BETWEEN AND 的分片处理。如果没配置范围分片算法,而 SQL 中又用到 BETWEEN AND 或者 like等,那么 SQL 将按全库、表路由的方式逐一执行,查询性能会很差需要特别注意。

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

  1. public class MyShardingAlgorithm implements PreciseShardingAlgorithm<T> {
  2. @Override
  3. public String doSharding(Collection<String> databaseNames, PreciseShardingValue<T> shardingValue) {
  4. //todo
  5. return null;
  6. }
  7. }

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

  1. public class MyShardingAlgorithm implements RangeShardingAlgorithm<T> {
  2. @Override
  3. public Collection<String> doSharding(Collection<String> databaseNames, RangeShardingValue<T> rangeShardingValue) {
  4. //todo
  5. return null;
  6. }
  7. }

三、复合分片策略:

1、使用场景:SQL 语句中有>>=<=<=IN 和 BETWEEN AND 等操作符,且复合分片策略支持对多个分片健操作。

2、实现方法:自定义复合分片策略要实现 ComplexKeysShardingAlgorithm 接口,重新 doSharding()方法。

  1. public class MyDBComplexKeysShardingAlgorithm implements ComplexKeysShardingAlgorithm<Integer> {
  2. @Override
  3. public Collection<String> doSharding(Collection<String> databaseNames, ComplexKeysShardingValue<Integer> complexKeysShardingValue) {
  4. // 得到每个分片健对应的值
  5. Collection<Integer> orderIdValues = this.getShardingValue(complexKeysShardingValue, "order_id");
  6. Collection<Integer> userIdValues = this.getShardingValue(complexKeysShardingValue, "user_id");
  7. List<String> shardingSuffix = new ArrayList<>();
  8. // 对两个分片健同时取模的方式分库
  9. for (Integer userId : userIdValues) {
  10. for (Integer orderId : orderIdValues) {
  11. String suffix = userId % 2 + "_" + orderId % 2;
  12. for (String databaseName : databaseNames) {
  13. if (databaseName.endsWith(suffix)) {
  14. shardingSuffix.add(databaseName);
  15. }
  16. }
  17. }
  18. }
  19. return shardingSuffix;
  20. }
  21. private Collection<Integer> getShardingValue(ComplexKeysShardingValue<Integer> shardingValues, final String key) {
  22. Collection<Integer> valueSet = new ArrayList<>();
  23. Map<String, Collection<Integer>> columnNameAndShardingValuesMap = shardingValues.getColumnNameAndShardingValuesMap();
  24. if (columnNameAndShardingValuesMap.containsKey(key)) {
  25. valueSet.addAll(columnNameAndShardingValuesMap.get(key));
  26. }
  27. return valueSet;
  28. }
  29. }

四、Hint分片策略:

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

(2)使用方法:实现 HintShardingAlgorithm 接口并重写 doSharding()方法。

  1. public class MyTableHintShardingAlgorithm implements HintShardingAlgorithm<String> {
  2. @Override
  3. public Collection<String> doSharding(Collection<String> tableNames, HintShardingValue<String> hintShardingValue) {
  4. //todo
  5. return null;
  6. }
  7. }

自定义完算法只实现了一部分,还需要在调用 SQL 前通过 HintManager 指定分库、分表信息。由于每次添加的规则都放在 ThreadLocal 内,所以要先执行 clear() 清除掉上一次的规则,否则会报错;addDatabaseShardingValue 设置分库分片健键值,addTableShardingValue设置分表分片健键值。setMasterRouteOnly 读写分离强制读主库,避免造成主从复制导致的延迟。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/木道寻08/article/detail/756632
推荐阅读
相关标签
  

闽ICP备14008679号