js css html

shardindjdbc-range策略

2022-09-12  本文已影响0人  念䋛

StandardShardingStrategy策略
只支持单分片键的标准分片策略。
配置参数:standard.sharding-column 分片键;
standard.precise.algorithm-class-name 精确分片算法类名;
standard.range-algorithm.class-name 范围分片算法类名
说明:
其中精确分片算法是必须提供的,而范围分片算法则是可选的.
精确查找是支持in和=,数据的插入是通过精确策略,按照范围查找是按照范围分片支持BETWEEN AND、>、<、>=、<=进行分片的场景
sql和源码
https://gitee.com/zhangjijige/shardingjdbc.git

spring:
  main:
    allow-bean-definition-overriding: true
  shardingsphere:
    # 参数配置,显示 sql
    props:
      sql:
        show: true
    # 配置数据源
    datasource:
      # 数据源别名
      names: db1
      # db1数据源信息
      db1:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://127.0.0.1:3306/shardingjdbc?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT
        username: root
        password: root
    sharding:
      # 默认数据源
      default-data-source-name: db1
      tables:
        # 逻辑表名
        tbl_order:
          # 指定tbl_order的数据节点
          actual-data-nodes: db1.tbl_order_$->{0..3}
          # 分布式主键配置
          key-generator:
            # 分布式主键列
            column: order_id
            # 分布式主键生成策略
            type: SNOWFLAKE
          # 分表策略
          table-strategy:
            standard:
              sharding-column: order_id
              # 精确分片算法
              precise-algorithm-class-name: com.example.shardingjdbc.sharding.algorithm.MyPreciseShardingAlgorithm
              # 范围分片算法
              range-algorithm-class-name: com.example.shardingjdbc.sharding.algorithm.MyRangeShardingAlgorithm
mybatis:
  mapper-locations: classpath:mapper/*.xml

当范围和精确策略一起使用的时候,要注意逻辑性,比如插入数据时候按照时间分片,1月份插入1月份数据库,按照范围查询的时候查询1月份到3月份的数据,这样数据是能对上的,不能插入数据按照年插入到不同数据库,查询的时候按照月份查询,数据就对不上了
MyPreciseShardingAlgorithm精确分片策略类

public class MyPreciseShardingAlgorithm implements PreciseShardingAlgorithm<Long> {
    /**
     * tableNames 对应分片库中所有分片表的集合
     * shardingValue 为分片属性,其中 logicTableName 为逻辑表,columnName 分片健(字段),value 为从 SQL 中解析出的分片健的值
     */
    @Override
    public String doSharding(Collection<String> tableList, PreciseShardingValue<Long> shardingValue) {
        for (String table: tableList) {
            String orderIdLastValue = String.valueOf(shardingValue.getValue());
            int value = Integer.parseInt(orderIdLastValue.substring(orderIdLastValue.length() - 1)) % tableList.size();
            if (table.endsWith(String.valueOf(value))) {
                return table;
            }
        }
        throw new IllegalArgumentException();
    }
}

MyRangeShardingAlgorithm范围策略

public class MyRangeShardingAlgorithm implements RangeShardingAlgorithm<Long>{
    @Override
    public Collection<String> doSharding(Collection<String> tableNames, RangeShardingValue<Long> shardingValue) {
        Set<String> result = new LinkedHashSet<>();

        // 获取范围的起始值和终止值
        Long leftOrderId = shardingValue.getValueRange().lowerEndpoint();
        Long rightOrderId = shardingValue.getValueRange().upperEndpoint();

        for (Long curOrderId = leftOrderId; curOrderId <= rightOrderId; ++curOrderId) {
            String orderIdStr = String.valueOf(curOrderId);

            for (String tableName: tableNames) {
                int value = Integer.parseInt(orderIdStr.substring(orderIdStr.length() - 1)) % tableNames.size();
                if (tableName.endsWith(String.valueOf(value))) {
                    result.add(tableName);
                }
            }
        }
        return result;
    }
}

没有配置分库策略
按照范围查找,主要是针对分表,在数据库方面是要轮询所有的数据库,策略类的入参


image.png
image.png

可以看到tableNames是数据表,数据库呢是要遍历的


image.png
配置分库策略
    sharding:
      # 默认数据源
     # default-data-source-name: db0
      tables:
        # 逻辑表名
        tbl_order:
          # 指定tbl_order的数据节点
          actual-data-nodes: db$->{0..1}.tbl_order_$->{0..3}
          # 分布式主键配置
          key-generator:
            # 分布式主键列
            column: order_id
            # 分布式主键生成策略
            type: SNOWFLAKE
          # 分库策略
          database-strategy:
            standard:
              sharding-column: user_id
              precise-algorithm-class-name: com.example.shardingjdbc.sharding.algorithm.DBPreciseShardingAlgorithm
          # 分表策略
          table-strategy:
            standard:
              sharding-column: order_id
              # 精确分片算法
              precise-algorithm-class-name: com.example.shardingjdbc.sharding.algorithm.MyPreciseShardingAlgorithm
              # 范围分片算法
              range-algorithm-class-name: com.example.shardingjdbc.sharding.algorithm.MyRangeShardingAlgorithm

配置了分库策略
按照DBPreciseShardingAlgorithm类的返回值决定从哪个库获取数据
分库建为user_id 也就是在查询sql的时候要有user_id作为条件,否则遍历所有的数据库
参考源码
org.apache.shardingsphere.core.route.type.standard.StandardRoutingEngine#routeDataSources
这里就不分析源码了,可以通过debug的方式看没有配置分库策略,和配置了分库策略但是sql语句中没有user_id作为条件的情况

上一篇下一篇

猜你喜欢

热点阅读