美文网首页js css html
shardindjdbc-range策略

shardindjdbc-range策略

作者: 念䋛 | 来源:发表于2022-09-12 19:27 被阅读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作为条件的情况

    相关文章

      网友评论

        本文标题:shardindjdbc-range策略

        本文链接:https://www.haomeiwen.com/subject/shlqortx.html