Shardingsphere read-write separation + sub-table [notes]

Shardingsphere read-write separation + sub-table


Frameworks used: mybatis-plus, druid, shardingsphere-jdbc-spring-boot-starter

  1. Dependency (gradle configuration, maven corresponds to mvnrepository query)
    implementation 'com.alibaba:druid:1.2.8'
    implementation('com.baomidou:mybatis-plus-boot-starter:3.4.3')
    implementation 'org.postgresql:postgresql:42.3.3'
    implementation 'org.apache.shardingsphere:sharding-jdbc-spring-boot-starter:4.1.1'
    implementation 'org.apache.shardingsphere:sharding-jdbc-spring-namespace:4.1.1'
  1. yml configuration
spring:
  shardingsphere:
    # 是否打印sql
    props:
      sql.show: true
    datasource:
      # 库1 的配置
      db1:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: org.postgresql.Driver
        url: jdbc:postgresql://localhost:5432/dd_test
        username: postgres
        password: 123456
      # 库2 的配置
      db1-slave0:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: org.postgresql.Driver
        url: jdbc:postgresql://localhost:5433/dd_test
        username: postgres
        password: 123456
      names: db1,db1-slave0
    sharding:
      # 默认的库
      default-data-source-name: db1
      # 绑定的表 不配置也没找出啥问题
      binding-tables: dd_order,order_sku
      default-table-strategy:
        none:
      default-database-strategy:
        none:
      # 配置表的分片规则
      tables:
        # 指定某个表的分片配置
        dd_order:
          # 这个配置是告诉sharding有多少个库和多少个表
          actual-data-nodes: ms.dd_order_$->{
    
    1..7}
          #分库策略
          database-strategy:
            none:
            # 行表达式
          #            inline:
          #              # 配置表分片的字段
          #              sharding-column: ship_id
          #              # 配置表分片算法
          #              algorithm-expression: dd_order_$->{ship_id % 7 +1}
          # 主键生成策略(如果是自动生成的,在插入数据的sql中就不要传id,null也不行,直接插入字段中就不要有主键的字段)
          key-generator:
            # 对应的数据库表的主键
            column: id
            # 生成方式, 雪花模式
            type: SNOWFLAKE
          # 配置表分片策略
          table-strategy:
            standard:
              sharding-column: id
              precise-algorithm-class-name: cn.venny.shardingsphere.CustomShardingPreciseAlgorithm
              range-algorithm-class-name: cn.venny.shardingsphere.CustomShardingRangeAlgorithm
        # 指定某个表的分片配置
        order_sku:
          # 这个配置是告诉sharding有多少个库和多少个表
          actual-data-nodes: ms.order_sku_$->{
    
    1..9}
          #分库策略
          database-strategy:
            none:
          # 主键生成策略(如果是自动生成的,在插入数据的sql中就不要传id,null也不行,直接插入字段中就不要有主键的字段)
          key-generator:
            # 对应的数据库表的主键
            column: id
            # 生成方式, 雪花模式
            type: SNOWFLAKE
          # 配置表分片策略
          table-strategy:
            standard:
              sharding-column: id
              precise-algorithm-class-name: cn.venny.shardingsphere.CustomShardingPreciseAlgorithm
              range-algorithm-class-name: cn.venny.shardingsphere.CustomShardingRangeAlgorithm
      masterSlaveRules:
        ms:
          name: ms
          master-data-source-name: db1
          slave-data-source-names: db1-slave0
          load-balance-algorithm-type: ROUND_ROBIN
  1. 2 algorithm codes:
  • tools used
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author Vick C
 * @version 1.0
 * @date 2022/3/8 22:56
 */
public class PatternUtils {
    
    

    private static final Pattern SHARDING_TABLE_RULE = Pattern.compile("\\d");

    public static String parseNum(String string) {
    
    
        if (string == null || string.length() < 1) {
    
    
            return null;
        }

        Matcher matcher = SHARDING_TABLE_RULE.matcher(string);

        StringBuilder sb = new StringBuilder();

        while (matcher.find()) {
    
    
            sb.append(matcher.group());
        }

        return sb.toString();
    }
}

  • first algorithm
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingValue;

import java.util.Collection;

/**
 * @author Vick C
 * @version 1.0
 * @date 2022/3/8 22:52
 */
public class CustomShardingPreciseAlgorithm implements PreciseShardingAlgorithm<String> {
    
    
	/** dd_order分7张表 */
    private static final int ORDER_TABLE_NUM = 7;
    /** order_sku分9张表 */
    private static final int ORDER_SKU_TABLE_NUM = 9;

    @Override
    public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<String> shardingValue) {
    
    
        String columnName = shardingValue.getColumnName();

        if (!"id".equals(columnName)) {
    
    
            return null;
        }
		// 自定义正则表达式
        String s = PatternUtils.parseNum(shardingValue.getValue());
		// 工具类用spring即可
        if (StringUtils.isEmpty(s)) {
    
    
            return null;
        }

        long num = Long.parseLong(s);

        long remain = 1;
        if (shardingValue.getLogicTableName().contains("order_sku")) {
    
    
            remain = num % ORDER_SKU_TABLE_NUM + 1;
        } else {
    
    
            remain = num % ORDER_TABLE_NUM + 1;
        }

        for (String availableTargetName : availableTargetNames) {
    
    
            if (availableTargetName.endsWith(String.valueOf(remain))) {
    
    
                return availableTargetName;
            }
        }

        return null;
    }
}
  • second algorithm

import com.google.common.collect.Range;
import org.apache.shardingsphere.api.sharding.standard.RangeShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.RangeShardingValue;

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

/**
 * @author Vick C
 * @version 1.0
 * @date 2022/3/8 22:59
 */
public class CustomShardingRangeAlgorithm implements RangeShardingAlgorithm<String> {
    
    
	/** dd_order分7张表 */
    private static final int ORDER_TABLE_NUM = 7;
    /** order_sku分9张表 */
    private static final int ORDER_SKU_TABLE_NUM = 9;

    @Override
    public Collection<String> doSharding(Collection<String> availableTargetNames, RangeShardingValue<String> shardingValue) {
    
    
        String columnName = shardingValue.getColumnName();

        if ("id".equals(columnName)) {
    
    
            Range<String> valueRange = shardingValue.getValueRange();
            String logicTableName = shardingValue.getLogicTableName();
            String lowerTable = calcTableValue(logicTableName, valueRange.lowerEndpoint(), availableTargetNames);
            String upperTable = calcTableValue(logicTableName, valueRange.upperEndpoint(), availableTargetNames);

            if (lowerTable != null && upperTable != null) {
    
    
                List<String> list = CollectionUtils.singleList(lowerTable);
                list.add(upperTable);
                return list;
            }
        }

        return null;
    }

    private String calcTableValue(String logicTableName, String lowerEndpoint, Collection<String> availableTargetNames) {
    
    
        String s = PatternUtils.parseNum(lowerEndpoint);

        if (StringUtils.notEmpty(s)) {
    
    
            long num = Long.parseLong(s);
            long remain = 1;
            if (logicTableName.contains("order_sku")) {
    
    
                remain = num % ORDER_SKU_TABLE_NUM + 1;
            } else {
    
    
                remain = num % ORDER_TABLE_NUM + 1;
            }
            for (String availableTargetName : availableTargetNames) {
    
    
                if (availableTargetName.endsWith(String.valueOf(remain))) {
    
    
                    return availableTargetName;
                }
            }
        }

        return null;
    }
}
  1. Database table creation
    slightly...注意shardingsphere不会自动建表,所有的表都要手动建
    insert image description here
  2. Test (slightly...)

pg uses insert into...on conflict (field name) do update set...successfully inserts into a different table and
uses the mybaits save() method to insert into a different table

Guess you like

Origin blog.csdn.net/qq_41070393/article/details/123417744