sharding-jdbc四种分片策略

一、标准分片策略(standard)

1、精确分片

配置文件

spring:
  shardingsphere:
    #开启sql显示
    props:
      sql:
        show: true
    datasource:
      # 配置数据源
      names: db0,db1
      db0:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://127.0.0.1:3306/sharding_test_0?useUnicode=true&character_set_server=utf8mb4&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai
        username: root
        password: root
      db1:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://127.0.0.1:3306/sharding_test_1?useUnicode=true&character_set_server=utf8mb4&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai
        username: root
        password: root
    sharding:
      #唯一库数据
      default-data-source-name: db0
      #分库
      default-database-strategy:
        standard:
          # 添加数据分库字段(根据字段插入数据到那个表)
          sharding-column: id
          #精确分片
          precise-algorithm-class-name: com.example.sharding_test.strategy.database.DatabasePreciseAlgorithm
      #分表
      tables:
        #表名
        db_user:
          actual-data-nodes: db$->{0..1}.db_user_$->{0..2}
          key-generator:
            column: id  # 主键ID
            type: SNOWFLAKE  # 生成策略雪花id
          table-strategy:
            standard:
              sharding-column: id
              #精确分片
              precise-algorithm-class-name: com.example.sharding_test.strategy.table.TablePreciseAlgorithm


分库规则

package com.example.sharding_test.strategy.database;

import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingValue;

import java.util.Collection;

/**
 * 精确分片
 *
 * @author shuai
 * @since 2023-03-19
 */
public class DatabasePreciseAlgorithm implements PreciseShardingAlgorithm<Long> {
    /**
     * 精确分片
     * @param collection 数据源集合
     * @param preciseShardingValue 分片参数
     * @return 数据库
     */
    @Override
    public String doSharding(Collection<String> collection, PreciseShardingValue<Long> preciseShardingValue) {
        //分片键的值
        Long value = preciseShardingValue.getValue();
        String dbName = "db" + (value % 2);
        if(!collection.contains(dbName)){
           throw new UnsupportedOperationException("数据源"+ dbName + "不存在");
        }
        return dbName;
    }
}


分表规则

package com.example.sharding_test.strategy.database;

import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingValue;

import java.util.Collection;

/**
 * 精确分片
 *
 * @author shuai
 * @since 2023-03-19
 */
public class DatabasePreciseAlgorithm implements PreciseShardingAlgorithm<Long> {
    /**
     * 精确分片
     * @param collection 数据源集合
     * @param preciseShardingValue 分片参数
     * @return 数据库
     */
    @Override
    public String doSharding(Collection<String> collection, PreciseShardingValue<Long> preciseShardingValue) {
        //分片键的值
        Long value = preciseShardingValue.getValue();
        String dbName = "db" + (value % 2);
        if(!collection.contains(dbName)){
           throw new UnsupportedOperationException("数据源"+ dbName + "不存在");
        }
        return dbName;
    }
}


2、范围分片

配置文件

spring:
  shardingsphere:
    #开启sql显示
    props:
      sql:
        show: true
    datasource:
      # 配置数据源
      names: db0,db1
      db0:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://127.0.0.1:3306/sharding_test_0?useUnicode=true&character_set_server=utf8mb4&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai
        username: root
        password: root
      db1:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://127.0.0.1:3306/sharding_test_1?useUnicode=true&character_set_server=utf8mb4&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai
        username: root
        password: root
    sharding:
      #唯一库数据
      default-data-source-name: db0
      #分库
      default-database-strategy:
        standard:
          # 添加数据分库字段(根据字段插入数据到那个表)
          sharding-column: id
          #精确分片
          precise-algorithm-class-name: com.example.sharding_test.strategy.database.DatabasePreciseAlgorithm
          #范围分片
          range-algorithm-class-name: com.example.sharding_test.strategy.database.DatabaseRangeAlgorithm          
      #分表
      tables:
        #表名
        db_user:
          actual-data-nodes: db$->{0..1}.db_user_$->{0..2}
          key-generator:
            column: id  # 主键ID
            type: SNOWFLAKE  # 生成策略雪花id
          table-strategy:
            standard:
              sharding-column: id
              #精确分片
              precise-algorithm-class-name: com.example.sharding_test.strategy.table.TablePreciseAlgorithm
              #范围分片
              range-algorithm-class-name: com.example.sharding_test.strategy.table.TableRangeAlgorithm

分库规则

package com.example.sharding_test.strategy.database;

import org.apache.shardingsphere.api.sharding.standard.RangeShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.RangeShardingValue;

import java.util.Collection;

/**
 * 范围分片
 *
 * @author shuai
 * @since 2023-03-19
 */
public class DatabaseRangeAlgorithm implements RangeShardingAlgorithm<Long> {
    /**
     * 范围分片
     * @param collection 数据源集合
     * @param rangeShardingValue 分片参数
     * @return 直接返回源
     */
    @Override
    public Collection<String> doSharding(Collection<String> collection, RangeShardingValue<Long> rangeShardingValue) {
        return collection;
    }
}


分表规则

package com.example.sharding_test.strategy.table;

import org.apache.shardingsphere.api.sharding.standard.RangeShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.RangeShardingValue;

import java.util.Arrays;
import java.util.Collection;

/**
 * 范围分片
 *
 * @author shuai
 * @since 2023-03-19
 */
public class TableRangeAlgorithm implements RangeShardingAlgorithm<Long> {
    /**
     * 范围分片
     * @param collection 数据源集合
     * @param rangeShardingValue 分片参数
     * @return 直接返回源
     */
    @Override
    public Collection<String> doSharding(Collection<String> collection, RangeShardingValue<Long> rangeShardingValue) {
        //逻辑表名称
        String logicTableName = rangeShardingValue.getLogicTableName();
        return Arrays.asList(logicTableName+"_0",logicTableName+"_1",logicTableName+"_2");
    }
}


行表达式分片策略(inline)

配置文件(需要注释其他的分片规则)

spring:
  shardingsphere:
    #开启sql显示
    props:
      sql:
        show: true
    datasource:
      # 配置数据源
      names: db0,db1
      db0:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://127.0.0.1:3306/sharding_test_0?useUnicode=true&character_set_server=utf8mb4&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai
        username: root
        password: root
      db1:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://127.0.0.1:3306/sharding_test_1?useUnicode=true&character_set_server=utf8mb4&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai
        username: root
        password: root
    sharding:
      #唯一库数据
      default-data-source-name: db0
      #分库
      default-database-strategy:
#        standard:
#          # 添加数据分库字段(根据字段插入数据到那个表)
#          sharding-column: id
#          #精确分片
#          precise-algorithm-class-name: com.example.sharding_test.strategy.database.DatabasePreciseAlgorithm
#          #范围分片
#          range-algorithm-class-name: com.example.sharding_test.strategy.database.DatabaseRangeAlgorithm
        inline:
          # 添加数据分表字段(根据字段插入数据到那个表)
          sharding-column: id
          # 分片算法表达式 => 通过id取余
          algorithm-expression: db$->{id % 2}
      #分表
      tables:
        #表名
        db_user:
          actual-data-nodes: db$->{0..1}.db_user_$->{0..2}
          key-generator:
            column: id  # 主键ID
            type: SNOWFLAKE  # 生成策略雪花id
          table-strategy:
#            standard:
#              sharding-column: id
#              #精确分片
#              precise-algorithm-class-name: com.example.sharding_test.strategy.table.TablePreciseAlgorithm
#              #范围分片
#              range-algorithm-class-name: com.example.sharding_test.strategy.table.TableRangeAlgorithm
            inline:
              # 添加数据分表字段(根据字段插入数据到那个表)
              sharding-column: id
              # 分片算法表达式 => 通过id取余
              algorithm-expression: db_user_$->{id % 3}


分库规则与分表规则可直接使用groovy脚本
例:db_user_$->{id % 3}

复合分片策略(complex)

配置文件

spring:
  shardingsphere:
    #开启sql显示
    props:
      sql:
        show: true
    datasource:
      # 配置数据源
      names: db0,db1
      db0:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://127.0.0.1:3306/sharding_test_0?useUnicode=true&character_set_server=utf8mb4&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai
        username: root
        password: root
      db1:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://127.0.0.1:3306/sharding_test_1?useUnicode=true&character_set_server=utf8mb4&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai
        username: root
        password: root
    sharding:
      #唯一库数据
      default-data-source-name: db0
      #分库
      default-database-strategy:
#        standard:
#          # 添加数据分库字段(根据字段插入数据到那个表)
#          sharding-column: id
#          #精确分片
#          precise-algorithm-class-name: com.example.sharding_test.strategy.database.DatabasePreciseAlgorithm
#          #范围分片
#          range-algorithm-class-name: com.example.sharding_test.strategy.database.DatabaseRangeAlgorithm
#        #行分片
#        inline:
#          # 添加数据分表字段(根据字段插入数据到那个表)
#          sharding-column: id
#          # 分片算法表达式 => 通过id取余
#          algorithm-expression: db$->{id % 2}
        #复合分片
         complex:
           sharding-columns: id,age
           algorithm-class-name: com.example.sharding_test.strategy.database.DatabaseComplexAlgorithm

      #分表
      tables:
        #表名
        db_user:
          actual-data-nodes: db$->{0..1}.db_user_$->{0..2}
          key-generator:
            column: id  # 主键ID
            type: SNOWFLAKE  # 生成策略雪花id
          table-strategy:
#            standard:
#              sharding-column: id
#              #精确分片
#              precise-algorithm-class-name: com.example.sharding_test.strategy.table.TablePreciseAlgorithm
#              #范围分片
#              range-algorithm-class-name: com.example.sharding_test.strategy.table.TableRangeAlgorithm
#            inline:
#              # 添加数据分表字段(根据字段插入数据到那个表)
#              sharding-column: id
#              # 分片算法表达式 => 通过id取余
#              algorithm-expression: db_user_$->{id % 3}
            #复合分片
            complex:
              sharding-columns: id,age
              algorithm-class-name: com.example.sharding_test.strategy.table.TableComplexAlgorithm

分库规则

package com.example.sharding_test.strategy.database;

import org.apache.shardingsphere.api.sharding.complex.ComplexKeysShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.complex.ComplexKeysShardingValue;
import org.apache.shardingsphere.api.sharding.standard.RangeShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.RangeShardingValue;
import org.assertj.core.util.Lists;

import java.util.Collection;
import java.util.List;

/**
 * 复合分片
 *
 * @author shuai
 * @since 2023-03-19
 */
public class DatabaseComplexAlgorithm implements ComplexKeysShardingAlgorithm<Integer> {


    /**
     *
     * @param collection 数据源集合
     * @param complexKeysShardingValue 分片键的值集合
     * @return 需要查找的数据源集合
     */
    @Override
    public Collection<String> doSharding(Collection<String> collection, ComplexKeysShardingValue<Integer> complexKeysShardingValue) {
        //获取age的值
        Collection<Integer> ageValues = complexKeysShardingValue.getColumnNameAndShardingValuesMap().get("age");
        List<String> dbs = Lists.newArrayList();
        //通过age取模
        ageValues.forEach(item->{
            String dbName = "db"+((item+3)%2);
            dbs.add(dbName);
        });
        return dbs;
    }
}


分表规则

package com.example.sharding_test.strategy.table;

import org.apache.shardingsphere.api.sharding.complex.ComplexKeysShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.complex.ComplexKeysShardingValue;
import org.apache.shardingsphere.api.sharding.standard.RangeShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.RangeShardingValue;
import org.assertj.core.util.Lists;

import java.util.Arrays;
import java.util.Collection;
import java.util.List;

/**
 * 复合分片
 *
 * @author shuai
 * @since 2023-03-19
 */
public class TableComplexAlgorithm implements ComplexKeysShardingAlgorithm<Integer> {

    @Override
    public Collection<String> doSharding(Collection<String> collection, ComplexKeysShardingValue<Integer> complexKeysShardingValue) {
        //获取age的值
        Collection<Integer> ageValues = complexKeysShardingValue.getColumnNameAndShardingValuesMap().get("age");
        List<String> dbs = Lists.newArrayList();
        //通过age取模
        ageValues.forEach(item->{
            String dbName = "db_user_"+((item+3)%3);
            dbs.add(dbName);
        });
        return dbs;
    }
}


Hint分片策略(hint)

配置文件(需要注释其他的分片规则)

spring:
  shardingsphere:
    #开启sql显示
    props:
      sql:
        show: true
    datasource:
      # 配置数据源
      names: db0,db1
      db0:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://127.0.0.1:3306/sharding_test_0?useUnicode=true&character_set_server=utf8mb4&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai
        username: root
        password: root
      db1:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://127.0.0.1:3306/sharding_test_1?useUnicode=true&character_set_server=utf8mb4&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai
        username: root
        password: root
    sharding:
      #唯一库数据
      default-data-source-name: db0
      #分库
      default-database-strategy:
#        standard:
#          # 添加数据分库字段(根据字段插入数据到那个表)
#          sharding-column: id
#          #精确分片
#          precise-algorithm-class-name: com.example.sharding_test.strategy.database.DatabasePreciseAlgorithm
#          #范围分片
#          range-algorithm-class-name: com.example.sharding_test.strategy.database.DatabaseRangeAlgorithm
        #行分片
        inline:
          # 添加数据分表字段(根据字段插入数据到那个表)
          sharding-column: id
          # 分片算法表达式 => 通过id取余
          algorithm-expression: db$->{id % 2}
#        #复合分片
#         complex:
#           sharding-columns: id,age
#           algorithm-class-name: com.example.sharding_test.strategy.database.DatabaseComplexAlgorithm

      #分表
      tables:
        #表名
        db_user:
          actual-data-nodes: db$->{0..1}.db_user_$->{0..2}
          key-generator:
            column: id  # 主键ID
            type: SNOWFLAKE  # 生成策略雪花id
          table-strategy:
#            standard:
#              sharding-column: id
#              #精确分片
#              precise-algorithm-class-name: com.example.sharding_test.strategy.table.TablePreciseAlgorithm
#              #范围分片
#              range-algorithm-class-name: com.example.sharding_test.strategy.table.TableRangeAlgorithm
#            inline:
#              # 添加数据分表字段(根据字段插入数据到那个表)
#              sharding-column: id
#              # 分片算法表达式 => 通过id取余
#              algorithm-expression: db_user_$->{id % 3}
#            #复合分片
#            complex:
#              sharding-columns: id,age
#              algorithm-class-name: com.example.sharding_test.strategy.table.TableComplexAlgorithm
            #强制分片
            hint:
              algorithm-class-name: com.example.sharding_test.strategy.table.TableHintAlgorithm


分表规则

package com.example.sharding_test.strategy.table;

import org.apache.shardingsphere.api.sharding.hint.HintShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.hint.HintShardingValue;

import java.util.Arrays;
import java.util.Collection;

/**
 * 精确分片
 *
 * @author shuai
 * @since 2023-03-19
 */
public class TableHintAlgorithm implements HintShardingAlgorithm<Integer> {


    @Override
    public Collection<String> doSharding(Collection<String> collection, HintShardingValue<Integer> hintShardingValue) {
        String logicTableName = hintShardingValue.getLogicTableName();
        String dbName = logicTableName+"_"+hintShardingValue.getValues().toArray()[0];
        return Arrays.asList(dbName);
    }
}


测试hint

    @Test
    void selectHintData(){
        HintManager manager = HintManager.getInstance();
        manager.addTableShardingValue("db_user",2);
        LambdaQueryWrapper<DbUser> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(DbUser::getAge,34);
        List<DbUser> dbUsers = dbUserMapper.selectList(wrapper);
        dbUsers.forEach(System.out::println);
    }

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值