3. Sharding-Jdbc核⼼流 程+多种分⽚策略

news2024/11/19 15:56:43

1. Sharding-Jdbc 分库分表执⾏核⼼流程

在这里插入图片描述

Sharding-JDBC执行流程
1. SQL解析 -> SQL优化 -> SQL路由 -> SQL改写 -> SQL执⾏-> 结果归并 ->返回结果
   简写为:解析->路由->改写->执⾏->结果归并
1.1 SQL解析
1. SQL解析过程分为词法解析,语法解析。
2. 词法解析:词法解析器用于将SQL拆解为不可再分的原子符号,称为Token,再使用语法解析器将SQL转换为抽象语法树。
3. 抽象语法树的遍历去提炼分片所需的上下文,并标记有可能需要的SQL改写。
1.2 两大SQL路由
1. 分片路由:带分片键,直接路由,标准路由,笛卡尔积路由
2. 广播路由:不带分片键,全库表路由,全库路由,全实例路由等。
1.3 SQL改写
1. Logic SQL逻辑表SQL,不能够直接在真实的数据库表中执行,SQL改写会将逻辑SQL改写为在真实数据库中可以正确执行的ActualSQL.
1.4 SQL执行
1. 采用自动化的执行引擎,将路由和改写完之后的Actual SQL安全且高效发送给底层数据源执行,自动平衡资源控制与执行效率
2. 两大模式:
	内存限制模式:数据库连接数量不做限制,多线程并发执行效率最大化,适用OLAP操作。
	连接限制模式:严格控制对一次操作所耗费的数据库连接数量,1库1线程,多库多线程使用OLTP操作,保证数据库资源被足够多应用使用。
1.5结果归并
从各个数据节点获取的多数据结果集,组合成为一个结果集并正确的返回至请求客户端,功能上可分为遍历,排序,分组,分页和聚合5种。
1. 结构划分两大类:
	流式-归并:每一次从结果集中获取到的数据,都通过逐条获取的方式返回正确的单条数据,它与数据库原生的返回结果集的方式最为契合。占用了额外的带宽,但不会导致内存暴涨,使用的最多。
	内存-归并:分片结果集的数据存储在内存中,再通过统一的分组,排序以及聚合等计算之后,再将其封装成为逐条访问的数据结果集返回,消耗内存。

2. 标准分⽚策略-精准分⽚算法《分表》

2.1 标准分⽚策略-精准分⽚算法
StandardShardingStrategy
1. 只⽀持【单分⽚键】,提供PreciseShardingAlgorithm和RangeShardingAlgorithm两个分⽚算法.
2. PreciseShardingAlgorithm 精准分⽚ 是必选的,⽤于处理=和IN的分⽚.
3. RangeShardingAlgorithm 范围分⽚ 是可选的,⽤于处理BETWEEN AND分⽚.
4. 如果不配置RangeShardingAlgorithm,如果SQL中⽤了BETWEEN AND语法,则将按照全库路由处理,性能下降.
2.2 代码
package com.dss.sharding.strategy;

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

import java.util.Collection;

/**
 *
 */
public class CustomTablePreciseShardingAlgorithm implements PreciseShardingAlgorithm<Long> {

    /**
     *
     * @param dataSourceNames 数据源集合
     *                      在分库时值为所有分片库的集合 databaseNames
     *                      分表时为对应分片库中所有分片表的集合 tablesNames
     *
     * @param shardingValue  分片属性,包括
     *                                  logicTableName 为逻辑表,
     *                                  columnName 分片健(字段),
     *                                  value 为从 SQL 中解析出的分片健的值
     * @return
     */
    @Override
    public String doSharding(Collection<String> dataSourceNames, PreciseShardingValue<Long> preciseShardingValue) {

        for(String datasourceName : dataSourceNames){

            /**通过取模,获取命中的表
             * value是0,则进⼊0库表,1则进⼊1库表
             */
            String value = preciseShardingValue.getValue() % dataSourceNames.size() + "";
            //product_order_0,表示命中库
            if(datasourceName.endsWith(value)){
                return  datasourceName;
            }
        }
        return null;
    }
}

2.3配置

spring.application.name=sharding-jdbc
server.port=8080


# 打印执行的数据库以及语句
spring.shardingsphere.props.sql.show=true

# 数据源 db0
spring.shardingsphere.datasource.names=ds0,ds1

# 第一个数据库
spring.shardingsphere.datasource.ds0.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds0.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ds0.jdbc-url=jdbc:mysql://127.0.0.1:3306/xdclass_shop_order_0?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
spring.shardingsphere.datasource.ds0.username=root
spring.shardingsphere.datasource.ds0.password=root


# 第二个数据库
spring.shardingsphere.datasource.ds1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds1.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ds1.jdbc-url=jdbc:mysql://127.0.0.1:3306/xdclass_shop_order_1?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
spring.shardingsphere.datasource.ds1.username=root
spring.shardingsphere.datasource.ds1.password=root


#配置workId
spring.shardingsphere.sharding.tables.product_order.key-generator.props.worker.id=1


#配置广播表
spring.shardingsphere.sharding.broadcast-tables=ad_config
spring.shardingsphere.sharding.tables.ad_config.key-generator.column=id
spring.shardingsphere.sharding.tables.ad_config.key-generator.type=SNOWFLAKE


#配置【默认分库策略】
#spring.shardingsphere.sharding.default-database-strategy.inline.sharding-column=user_id
#spring.shardingsphere.sharding.default-database-strategy.inline.algorithm-expression=ds$->{user_id % 2 }
#配置分库规则
#spring.shardingsphere.sharding.tables.product_order.database-strategy.inline.sharding-column=user_id
#spring.shardingsphere.sharding.tables.product_order.database-strategy.inline.algorithm-expression=ds$->{user_id % 2 }


#id生成策略
spring.shardingsphere.sharding.tables.product_order.key-generator.column=id
spring.shardingsphere.sharding.tables.product_order.key-generator.type=SNOWFLAKE

# 指定product_order表的数据分布情况,配置数据节点,行表达式标识符使用 ${...} 或 $->{...},
# 但前者与 Spring 本身的文件占位符冲突,所以在 Spring 环境中建议使用 $->{...}
#spring.shardingsphere.sharding.tables.product_order.actual-data-nodes=ds0.product_order_$->{0..1}
#spring.shardingsphere.sharding.tables.product_order.actual-data-nodes=ds$->{0..1}.product_order_$->{0..1}
# 指定product_order表的分片策略,分片策略包括【分片键和分片算法】
#spring.shardingsphere.sharding.tables.product_order.table-strategy.inline.sharding-column=id
#spring.shardingsphere.sharding.tables.product_order.table-strategy.inline.algorithm-expression=product_order_$->{id % 2}


# 指定product_order_item表的分片策略,分片策略包括【分片键和分片算法】
#spring.shardingsphere.sharding.tables.product_order_item.actual-data-nodes=ds$->{0..1}.product_order_item_$->{0..1}
#spring.shardingsphere.sharding.tables.product_order_item.table-strategy.inline.sharding-column=product_order_id
#spring.shardingsphere.sharding.tables.product_order_item.table-strategy.inline.algorithm-expression=product_order_item_$->{product_order_id % 2}

#配置绑定表
#spring.shardingsphere.sharding.binding‐tables[0] = product_order,product_order_item




#精准分片-水平分表
# 指定product_order表的数据分布情况,配置数据节点,Spring 环境中建议使用 $->{...}
spring.shardingsphere.sharding.tables.product_order.actual-data-nodes=ds0.product_order_$->{0..1}

#指定精准分片算法(水平分表)
spring.shardingsphere.sharding.tables.product_order.table-strategy.standard.sharding-column=id
spring.shardingsphere.sharding.tables.product_order.table-strategy.standard.precise-algorithm-class-name=com.dss.sharding.strategy.CustomTablePreciseShardingAlgorithm

2.4 测试
@Test
    public void testSaveProductOrder(){

        Random random = new Random();
        for(int i=0; i<20;i++){
            ProductOrderDO productOrderDO = new ProductOrderDO();
            productOrderDO.setCreateTime(new Date());
            productOrderDO.setNickname("PreciseShardingAlgorithm i="+i);
            productOrderDO.setOutTradeNo(UUID.randomUUID().toString().substring(0,32));
            productOrderDO.setPayAmount(100.00);
            productOrderDO.setState("PAY");

            productOrderDO.setUserId( Long.valueOf(random.nextInt(50)) );

            productOrderMapper.insert(productOrderDO);

        }

    }

3 标准分⽚策略-精准分⽚算法《分库分表》

3.1策略代码案例
package com.dss.sharding.strategy;

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

import java.util.Collection;



public class CustomDBPreciseShardingAlgorithm implements PreciseShardingAlgorithm<Long> {

    /**
     *
     * @param dataSourceNames 数据源集合
     *                      在分库时值为所有分片库的集合 databaseNames
     *                      分表时为对应分片库中所有分片表的集合 tablesNames
     *
     * @param shardingValue  分片属性,包括
     *                                  logicTableName 为逻辑表,
     *                                  columnName 分片健(字段),
     *                                  value 为从 SQL 中解析出的分片健的值
     * @return
     */
    @Override
    public String doSharding(Collection<String> dataSourceNames, PreciseShardingValue<Long> preciseShardingValue) {

        for(String datasourceName : dataSourceNames){

            String value = preciseShardingValue.getValue() % dataSourceNames.size() + "";
            //ds0、ds1
            if(datasourceName.endsWith(value)){
                return  datasourceName;
            }
        }
        return null;
    }
}


spring.application.name=sharding-jdbc
server.port=8080


# 打印执行的数据库以及语句
spring.shardingsphere.props.sql.show=true

# 数据源 db0
spring.shardingsphere.datasource.names=ds0,ds1

# 第一个数据库
spring.shardingsphere.datasource.ds0.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds0.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ds0.jdbc-url=jdbc:mysql://127.0.0.1:3306/xdclass_shop_order_0?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
spring.shardingsphere.datasource.ds0.username=root
spring.shardingsphere.datasource.ds0.password=root


# 第二个数据库
spring.shardingsphere.datasource.ds1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds1.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ds1.jdbc-url=jdbc:mysql://127.0.0.1:3306/xdclass_shop_order_1?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
spring.shardingsphere.datasource.ds1.username=root
spring.shardingsphere.datasource.ds1.password=root


#配置workId
spring.shardingsphere.sharding.tables.product_order.key-generator.props.worker.id=1


#配置广播表
spring.shardingsphere.sharding.broadcast-tables=ad_config
spring.shardingsphere.sharding.tables.ad_config.key-generator.column=id
spring.shardingsphere.sharding.tables.ad_config.key-generator.type=SNOWFLAKE


#配置【默认分库策略】
#spring.shardingsphere.sharding.default-database-strategy.inline.sharding-column=user_id
#spring.shardingsphere.sharding.default-database-strategy.inline.algorithm-expression=ds$->{user_id % 2 }
#配置分库规则
#spring.shardingsphere.sharding.tables.product_order.database-strategy.inline.sharding-column=user_id
#spring.shardingsphere.sharding.tables.product_order.database-strategy.inline.algorithm-expression=ds$->{user_id % 2 }


#id生成策略
spring.shardingsphere.sharding.tables.product_order.key-generator.column=id
spring.shardingsphere.sharding.tables.product_order.key-generator.type=SNOWFLAKE

# 指定product_order表的数据分布情况,配置数据节点,行表达式标识符使用 ${...} 或 $->{...},
# 但前者与 Spring 本身的文件占位符冲突,所以在 Spring 环境中建议使用 $->{...}
#spring.shardingsphere.sharding.tables.product_order.actual-data-nodes=ds0.product_order_$->{0..1}
#spring.shardingsphere.sharding.tables.product_order.actual-data-nodes=ds$->{0..1}.product_order_$->{0..1}
# 指定product_order表的分片策略,分片策略包括【分片键和分片算法】
#spring.shardingsphere.sharding.tables.product_order.table-strategy.inline.sharding-column=id
#spring.shardingsphere.sharding.tables.product_order.table-strategy.inline.algorithm-expression=product_order_$->{id % 2}


# 指定product_order_item表的分片策略,分片策略包括【分片键和分片算法】
#spring.shardingsphere.sharding.tables.product_order_item.actual-data-nodes=ds$->{0..1}.product_order_item_$->{0..1}
#spring.shardingsphere.sharding.tables.product_order_item.table-strategy.inline.sharding-column=product_order_id
#spring.shardingsphere.sharding.tables.product_order_item.table-strategy.inline.algorithm-expression=product_order_item_$->{product_order_id % 2}

#配置绑定表
#spring.shardingsphere.sharding.binding‐tables[0] = product_order,product_order_item




#精准分片-水平分表
# 指定product_order表的数据分布情况,配置数据节点,在 Spring 环境中建议使用 $->{...}
spring.shardingsphere.sharding.tables.product_order.actual-data-nodes=ds$->{0..1}.product_order_$->{0..1}


#指定精准分片算法(水平分库) 根据user_id分库
spring.shardingsphere.sharding.tables.product_order.database-strategy.standard.sharding-column=user_id
spring.shardingsphere.sharding.tables.product_order.database-strategy.standard.precise-algorithm-class-name=com.dss.sharding.strategy.CustomDBPreciseShardingAlgorithm

#指定精准分片算法(水平分表) 根据订单id分表
spring.shardingsphere.sharding.tables.product_order.table-strategy.standard.sharding-column=id
spring.shardingsphere.sharding.tables.product_order.table-strategy.standard.precise-algorithm-class-name=com.dss.sharding.strategy.CustomDBPreciseShardingAlgorithm


4 范围分⽚算法

4.1 RangeShardingAlgorithm 范围分⽚
1. ⽤于处理BETWEEN AND语法,没配置的话会报错 Cannot find range sharding strategy in sharding rule.
2. 主要是会根据 SQL中给出的分⽚健值范围值处理分库、分表逻辑.
4.2策略算法
package com.dss.sharding.strategy;

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

import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.Set;


public class CustomRangeShardingAlgorithm implements RangeShardingAlgorithm<Long> {
    /**
     *
     * @param dataSourceNames 数据源集合
     *                      在分库时值为所有分片库的集合 databaseNames
     *                      分表时为对应分片库中所有分片表的集合 tablesNames
     *
     * @param shardingValue  分片属性,包括
     *                                  logicTableName 为逻辑表,
     *                                  columnName 分片健(字段),
     *                                  value 为从 SQL 中解析出的分片健的值
     * @return
     */
    @Override
    public Collection<String> doSharding(Collection<String> dataSourceNames, RangeShardingValue<Long> shardingValue) {
        Set<String> result = new LinkedHashSet<>();

        //between 开始值
        Long lower  = shardingValue.getValueRange().lowerEndpoint();

        //between 结束值
        Long upper = shardingValue.getValueRange().upperEndpoint();

        for(long i=lower;i<=upper;i++){
            for(String datasource : dataSourceNames){
                String value = i % dataSourceNames.size() +"";
                if(datasource.endsWith(value)){
                    result.add(datasource);
                }
            }

        }
        return result;
    }
}

4.3 算法配置

spring.application.name=sharding-jdbc
server.port=8080


# 打印执行的数据库以及语句
spring.shardingsphere.props.sql.show=true

# 数据源 db0
spring.shardingsphere.datasource.names=ds0,ds1

# 第一个数据库
spring.shardingsphere.datasource.ds0.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds0.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ds0.jdbc-url=jdbc:mysql://127.0.0.1:3306/xdclass_shop_order_0?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
spring.shardingsphere.datasource.ds0.username=root
spring.shardingsphere.datasource.ds0.password=root


# 第二个数据库
spring.shardingsphere.datasource.ds1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds1.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ds1.jdbc-url=jdbc:mysql://127.0.0.1:3306/xdclass_shop_order_1?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
spring.shardingsphere.datasource.ds1.username=root
spring.shardingsphere.datasource.ds1.password=root


#配置workId
spring.shardingsphere.sharding.tables.product_order.key-generator.props.worker.id=1


#配置广播表
spring.shardingsphere.sharding.broadcast-tables=ad_config
spring.shardingsphere.sharding.tables.ad_config.key-generator.column=id
spring.shardingsphere.sharding.tables.ad_config.key-generator.type=SNOWFLAKE


#配置【默认分库策略】
#spring.shardingsphere.sharding.default-database-strategy.inline.sharding-column=user_id
#spring.shardingsphere.sharding.default-database-strategy.inline.algorithm-expression=ds$->{user_id % 2 }
#配置分库规则
#spring.shardingsphere.sharding.tables.product_order.database-strategy.inline.sharding-column=user_id
#spring.shardingsphere.sharding.tables.product_order.database-strategy.inline.algorithm-expression=ds$->{user_id % 2 }


#id生成策略
spring.shardingsphere.sharding.tables.product_order.key-generator.column=id
spring.shardingsphere.sharding.tables.product_order.key-generator.type=SNOWFLAKE

# 指定product_order表的数据分布情况,配置数据节点,行表达式标识符使用 ${...} 或 $->{...},
# 但前者与 Spring 本身的文件占位符冲突,所以在 Spring 环境中建议使用 $->{...}
#spring.shardingsphere.sharding.tables.product_order.actual-data-nodes=ds0.product_order_$->{0..1}
#spring.shardingsphere.sharding.tables.product_order.actual-data-nodes=ds$->{0..1}.product_order_$->{0..1}
# 指定product_order表的分片策略,分片策略包括【分片键和分片算法】
#spring.shardingsphere.sharding.tables.product_order.table-strategy.inline.sharding-column=id
#spring.shardingsphere.sharding.tables.product_order.table-strategy.inline.algorithm-expression=product_order_$->{id % 2}


# 指定product_order_item表的分片策略,分片策略包括【分片键和分片算法】
#spring.shardingsphere.sharding.tables.product_order_item.actual-data-nodes=ds$->{0..1}.product_order_item_$->{0..1}
#spring.shardingsphere.sharding.tables.product_order_item.table-strategy.inline.sharding-column=product_order_id
#spring.shardingsphere.sharding.tables.product_order_item.table-strategy.inline.algorithm-expression=product_order_item_$->{product_order_id % 2}

#配置绑定表
#spring.shardingsphere.sharding.binding‐tables[0] = product_order,product_order_item




#精准分片-水平分表
# 指定product_order表的数据分布情况,配置数据节点,Spring 环境中建议使用 $->{...}
#spring.shardingsphere.sharding.tables.product_order.actual-data-nodes=ds$->{0..1}.product_order_$->{0..1}
spring.shardingsphere.sharding.tables.product_order.actual-data-nodes=ds0.product_order_$->{0..1}


#指定精准分片算法(水平分库) 根据user_id分库
spring.shardingsphere.sharding.tables.product_order.database-strategy.standard.sharding-column=user_id
spring.shardingsphere.sharding.tables.product_order.database-strategy.standard.precise-algorithm-class-name=com.dss.sharding.strategy.CustomDBPreciseShardingAlgorithm

#指定精准分片算法(水平分表) 根据订单id分表
spring.shardingsphere.sharding.tables.product_order.table-strategy.standard.sharding-column=id
spring.shardingsphere.sharding.tables.product_order.table-strategy.standard.precise-algorithm-class-name=com.dss.sharding.strategy.CustomTablePreciseShardingAlgorithm

#范围分片(水平分表)
spring.shardingsphere.sharding.tables.product_order.table-strategy.standard.range-algorithm-class-name=com.dss.sharding.strategy.CustomRangeShardingAlgorithm

5. 复合分⽚算法

5.1 复合分⽚算法ComplexShardingStrategy
1. 提供对SQL语句中的=, IN和BETWEEN AND的分⽚操作,⽀持【多分⽚键】
2. 由于多分⽚键之间的关系复杂,Sharding-JDBC并未做过多的封装
3. ⽽是直接将分⽚键值组合以及分⽚操作符交于算法接⼝,全部由应⽤开发者实现,提供最⼤的灵活度。
5.2 自定义算法
package com.dss.sharding.strategy;

import org.apache.shardingsphere.api.sharding.complex.ComplexKeysShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.complex.ComplexKeysShardingValue;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;


public class CustomComplexKeysShardingAlgorithm implements ComplexKeysShardingAlgorithm<Long> {
    /**
     *
     * @param dataSourceNames 数据源集合
     *                      在分库时值为所有分片库的集合 databaseNames
     *                      分表时为对应分片库中所有分片表的集合 tablesNames
     *
     * @param shardingValue  分片属性,包括
     *                                  logicTableName 为逻辑表,
     *                                  columnName 分片健(字段),
     *                                  value 为从 SQL 中解析出的分片健的值
     * @return
     */
    @Override
    public Collection<String> doSharding(Collection<String> dataSourceNames, ComplexKeysShardingValue<Long> complexKeysShardingValue) {

        // 得到每个分片健对应的值
        Collection<Long> orderIdValues = this.getShardingValue(complexKeysShardingValue, "id");
        Collection<Long> userIdValues = this.getShardingValue(complexKeysShardingValue, "user_id");

        List<String> shardingSuffix = new ArrayList<>();
        // 对两个分片健取模的方式 product_order_0_0、product_order_0_1、product_order_1_0、product_order_1_1
        for (Long userId : userIdValues) {
            for (Long orderId : orderIdValues) {
                String suffix = userId % 2 + "_" + orderId % 2;
                for (String databaseName : dataSourceNames) {
                    if (databaseName.endsWith(suffix)) {
                        shardingSuffix.add(databaseName);
                    }
                }
            }
        }
        return shardingSuffix;
    }

    /**
     * shardingValue  分片属性,包括
     * logicTableName 为逻辑表,
     * columnNameAndShardingValuesMap 存储多个分片健 包括key-value
     * key:分片key,id和user_id
     * value:分片value,66和99
     *
     * @return shardingValues 集合
     */
    private Collection<Long> getShardingValue(ComplexKeysShardingValue<Long> shardingValues, final String key) {
        Collection<Long> valueSet = new ArrayList<>();
        Map<String, Collection<Long>> columnNameAndShardingValuesMap = shardingValues.getColumnNameAndShardingValuesMap();

        if (columnNameAndShardingValuesMap.containsKey(key)) {
            valueSet.addAll(columnNameAndShardingValuesMap.get(key));
        }
        return valueSet;
    }

}

5.3 配置(记得注释其他策略,否则报错)

spring.application.name=sharding-jdbc
server.port=8080


# 打印执行的数据库以及语句
spring.shardingsphere.props.sql.show=true

# 数据源 db0
spring.shardingsphere.datasource.names=ds0,ds1

# 第一个数据库
spring.shardingsphere.datasource.ds0.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds0.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ds0.jdbc-url=jdbc:mysql://127.0.0.1:3306/xdclass_shop_order_0?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
spring.shardingsphere.datasource.ds0.username=root
spring.shardingsphere.datasource.ds0.password=root


# 第二个数据库
spring.shardingsphere.datasource.ds1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds1.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ds1.jdbc-url=jdbc:mysql://127.0.0.1:3306/xdclass_shop_order_1?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
spring.shardingsphere.datasource.ds1.username=root
spring.shardingsphere.datasource.ds1.password=root


#配置workId
spring.shardingsphere.sharding.tables.product_order.key-generator.props.worker.id=1


#配置广播表
spring.shardingsphere.sharding.broadcast-tables=ad_config
spring.shardingsphere.sharding.tables.ad_config.key-generator.column=id
spring.shardingsphere.sharding.tables.ad_config.key-generator.type=SNOWFLAKE


#配置【默认分库策略】
#spring.shardingsphere.sharding.default-database-strategy.inline.sharding-column=user_id
#spring.shardingsphere.sharding.default-database-strategy.inline.algorithm-expression=ds$->{user_id % 2 }
#配置分库规则
#spring.shardingsphere.sharding.tables.product_order.database-strategy.inline.sharding-column=user_id
#spring.shardingsphere.sharding.tables.product_order.database-strategy.inline.algorithm-expression=ds$->{user_id % 2 }


#id生成策略
spring.shardingsphere.sharding.tables.product_order.key-generator.column=id
spring.shardingsphere.sharding.tables.product_order.key-generator.type=SNOWFLAKE

# 指定product_order表的数据分布情况,配置数据节点,行表达式标识符使用 ${...} 或 $->{...},
# 但前者与 Spring 本身的文件占位符冲突,所以在 Spring 环境中建议使用 $->{...}
#spring.shardingsphere.sharding.tables.product_order.actual-data-nodes=ds0.product_order_$->{0..1}
#spring.shardingsphere.sharding.tables.product_order.actual-data-nodes=ds$->{0..1}.product_order_$->{0..1}
# 指定product_order表的分片策略,分片策略包括【分片键和分片算法】
#spring.shardingsphere.sharding.tables.product_order.table-strategy.inline.sharding-column=id
#spring.shardingsphere.sharding.tables.product_order.table-strategy.inline.algorithm-expression=product_order_$->{id % 2}


# 指定product_order_item表的分片策略,分片策略包括【分片键和分片算法】
#spring.shardingsphere.sharding.tables.product_order_item.actual-data-nodes=ds$->{0..1}.product_order_item_$->{0..1}
#spring.shardingsphere.sharding.tables.product_order_item.table-strategy.inline.sharding-column=product_order_id
#spring.shardingsphere.sharding.tables.product_order_item.table-strategy.inline.algorithm-expression=product_order_item_$->{product_order_id % 2}

#配置绑定表
#spring.shardingsphere.sharding.binding‐tables[0] = product_order,product_order_item




#精准分片-水平分表
# 指定product_order表的数据分布情况,配置数据节点,Spring 环境中建议使用 $->{...}
#spring.shardingsphere.sharding.tables.product_order.actual-data-nodes=ds$->{0..1}.product_order_$->{0..1}
#spring.shardingsphere.sharding.tables.product_order.actual-data-nodes=ds0.product_order_$->{0..1}


#指定精准分片算法(水平分库) 根据user_id分库
#spring.shardingsphere.sharding.tables.product_order.database-strategy.standard.sharding-column=user_id
#spring.shardingsphere.sharding.tables.product_order.database-strategy.standard.precise-algorithm-class-name=com.dss.sharding.strategy.CustomDBPreciseShardingAlgorithm

#指定精准分片算法(水平分表) 根据订单id分表
#spring.shardingsphere.sharding.tables.product_order.table-strategy.standard.sharding-column=id
#spring.shardingsphere.sharding.tables.product_order.table-strategy.standard.precise-algorithm-class-name=com.dss.sharding.strategy.CustomTablePreciseShardingAlgorithm

#范围分片(水平分表)
#spring.shardingsphere.sharding.tables.product_order.table-strategy.standard.range-algorithm-class-name=com.dss.sharding.strategy.CustomRangeShardingAlgorithm



## 复合分片算法,order_id,user_id 同时作为分片健
spring.shardingsphere.sharding.tables.product_order.table-strategy.complex.sharding-columns=user_id,id
spring.shardingsphere.sharding.tables.product_order.table-strategy.complex.algorithm-class-name=com.dss.sharding.strategy.CustomComplexKeysShardingAlgorithm

6. Hint分⽚算法

6.1 简介
1. 这种分⽚策略⽆需配置⽂件进⾏配置分⽚健,分⽚健值也不再从 SQL中解析,外部⼿动指定分⽚健或分⽚库,让 SQL在指定的分库、分表中执⾏.
2. 通过Hint代码指定的⽅式⽽⾮SQL解析的⽅式分⽚的策略.
3. Hint策略会绕过SQL解析的,对于这些⽐较复杂的需要分⽚的查询,Hint分⽚策略性能可能会更好.
4. 可以指定sql去某个库某个表进⾏执⾏
6.2 编码
(⾃定义完算法只实现了⼀部分,需要在调⽤ SQL 前通过HintManager 指定分库、分表信息)
package com.dss.sharding.strategy;

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

import java.util.ArrayList;
import java.util.Collection;


public class CustomTableHintShardingAlgorithm implements HintShardingAlgorithm<Long> {
    /**
     *
     * @param dataSourceNames 数据源集合
     *                      在分库时值为所有分片库的集合 databaseNames
     *                      分表时为对应分片库中所有分片表的集合 tablesNames
     *
     * @param hintShardingValue  分片属性,包括
     *                                  logicTableName 为逻辑表,
     *                                  columnName 分片健(字段),hit策略此处为空 ""
     *
     *                                  value 【之前】都是 从 SQL 中解析出的分片健的值,用于取模判断
     *                                   HintShardingAlgorithm不再从SQL 解析中获取值,而是直接通过
     *                                   hintManager.addTableShardingValue("product_order", 1)参数进行指定
     * @return
     */

    @Override
    public Collection<String> doSharding(Collection<String> dataSourceNames, HintShardingValue<Long> hitShardingValue) {

        Collection<String> result = new ArrayList<>();
        for(String datasourceName: dataSourceNames){

            for(Long shardingValue : hitShardingValue.getValues()){

                String value = shardingValue % dataSourceNames.size()+"";

                if(datasourceName.endsWith(value)){
                    result.add(datasourceName);
                }
            }
        }
        return result;
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2243481.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

编程之路,从0开始:结构体详解

目录 前言 正文 1、结构体引入 2、结构体的声明 3、typedef 4、结构体的匿名声明 5、结构的自引用 &#xff08;1&#xff09;链表 &#xff08;2&#xff09;自引用 6、结构体内存对齐 &#xff08;1&#xff09;对齐规则 &#xff08;2&#xff09;题目 &#x…

01_MinIO部署(Windows单节点部署/Docker化部署)

单节点-Windows环境安装部署 在Windows环境安装MinIO&#xff0c;主要包含两个东西&#xff1a; MinIO Server&#xff08;minio.exe&#xff09;&#xff1a;应用服务本身MinIO Client&#xff08;mc.exe&#xff09;&#xff1a;MinIO客户端工具&#xff08;mc&#xff09;…

qt5半成品飞机大战小游戏

最近在学Qt&#xff0c;心血来潮做了个飞机大战小游戏&#xff0c;由于一些资源比较难找&#xff0c;就做了个半成品。效果图如下&#xff1a; 目前已做功能&#xff1a;人物飞机的自由移动&#xff0c;子弹的发射&#xff0c;子弹与敌机的物体碰撞,碰撞特效。 缺少功能&#x…

html 图片转svg 并使用svg路径来裁剪html元素

1.png转svg 工具地址: Vectorizer – 免费图像矢量化 打开svg图片,复制其中的path中的d标签的路径 查看生成的svg路径是否正确 在线SVG路径预览工具 - UU在线工具 2.在html中使用svg路径 <svg xmlns"http://www.w3.org/2000/svg" width"318px" height…

Android OpenGL ES详解——几何着色器

目录 一、概念 1、图元 2、几何着色器 1、输入类型 2、输出类型 3、输出顶点数量最大值限制 二、使用几何着色器 三、应用举例——造几个房子 四、应用举例——爆破物体 1、获取法向量 2、显示法线 五、应用举例——细分三角形 六、应用举例——广告牌技术 一、概…

基因组之全局互作热图可视化

引言 PlotHiC 是一个专为 Hi-C 数据可视化分析而设计的 Python 包。Hi-C 技术是一种能够检测染色体三维结构的实验方法&#xff0c;它能揭示 DNA 在细胞核内的三维组织结构。为了更好地展示和解释这些复杂的数据&#xff0c;PlotHiC[1] 可以帮助用户方便地绘制Hi-C 数据的热图。…

JVM详解:类的加载过程

JVM中类的加载主要分为三个部分&#xff0c;分别为加载&#xff08;loading&#xff09;&#xff0c;链接&#xff08;linking&#xff09;&#xff0c;初始化&#xff08;initing&#xff09;。其中加载负责的主要是讲类文件加载到内存中变为类对象&#xff0c;不过此时只有基…

FPGA开发流程

注&#xff1a;开发板&#xff1a;小梅哥的ACX720。本实验可直接运行在小梅哥的ACX720开发板上&#xff0c;后续的实验都可直接运行在小梅哥的ACX720上。 一、打开VIVADO并创建工程 1、双击VIVADO图标&#xff0c;打开vivado。 2、打开vivado界面打&#xff0c;点击有 Create …

免费开源!DBdoctor推出开源版系统诊断工具systool

​前言 在开发和运维过程中&#xff0c;经常会遇到难以定位的应用问题&#xff0c;我们通常需要借助Linux系统资源监控工具来辅助诊断。然而&#xff0c;系统的IO、网络、CPU使用率以及文件句柄等信息通常需要通过多个独立的命令工具来获取。在没有部署如Prometheus这样的综合…

Restful API接⼝简介及为什么要进⾏接⼝压测

一、RESTful API简介 在现代Web开发中&#xff0c;RESTful API已经成为一种标准的设计模式&#xff0c;用于构建和交互网络应用程序。本文将详细介绍RESTful API的基本概念、特点以及如何使用它来设计高效的API接口。 1. 基于协议 HTTP 或 HTTPS RESTful API通常使用HTTP&am…

R语言统计分析与MATLAB数学建模书籍推荐

文章目录 一、《R语言统计分析与可视化》1.1 内容核心1.2 内容简介 二、《MATLAB数学建模从入门到精通》2.1 关键点2.2 内容简介2.3 作者简介 一、《R语言统计分析与可视化》 R语言统计分析与可视化从入门到精通。学R语言、练语法、取数据、预处理、可视化、回归分析、方差分析…

智慧社区平台系统提升物业管理效率与居民生活质量

内容概要 智慧社区平台系统是为应对现代城市管理挑战而诞生的重要工具。随着城市化进程的加快&#xff0c;传统的物业管理方式已经难以满足日益增长的居民需求和管理复杂性。因此&#xff0c;引入智能化管理手段显得尤为重要。这个系统不仅仅是一个简单的软件&#xff0c;它是…

【ASR技术】WhisperX安装使用

介绍 WhisperX 是一个开源的自动语音识别&#xff08;ASR&#xff09;项目&#xff0c;由 m-bain 开发。该项目基于 OpenAI 的 Whisper 模型&#xff0c;通过引入批量推理、强制音素对齐和语音活动检测等技术。提供快速自动语音识别&#xff08;large-v2 为 70 倍实时&#xf…

STM32CUBEIDE FreeRTOS操作教程(九):eventgroup事件标志组

STM32CUBEIDE FreeRTOS操作教程&#xff08;九&#xff09;&#xff1a;eventgroup事件标志组 STM32CUBE开发环境集成了STM32 HAL库进行FreeRTOS配置和开发的组件&#xff0c;不需要用户自己进行FreeRTOS的移植。这里介绍最简化的用户操作类应用教程。以STM32F401RCT6开发板为…

力扣(leetcode)题目总结——动态规划篇

leetcode 经典题分类 链表数组字符串哈希表二分法双指针滑动窗口递归/回溯动态规划二叉树辅助栈 本系列专栏&#xff1a;点击进入 leetcode题目分类 关注走一波 前言&#xff1a;本系列文章初衷是为了按类别整理出力扣&#xff08;leetcode&#xff09;最经典题目&#xff0c…

计算器的实现

计算器的实现 计算器实现思路 我们⽇常写的计算表达式都是中缀表达式&#xff0c;也就是运算符在中间&#xff0c;运算数在两边&#xff0c;但是直接读取⽆ 法⻢上进⾏运算因为⼀个计算表达式还涉及运算符优先级问题。如&#xff1a; 都⽆法运算&#xff0c;因为后⾯还有括号优…

Python蓝桥杯刷题1

1.确定字符串是否包含唯一字符 题解&#xff1a;调用count函数计算每一个字符出现的次数&#xff0c;如果不等于1就输出no&#xff0c;并且结束循环&#xff0c;如果等于1就一直循环直到计算到最后一个字符&#xff0c;若最后一个字符也满足条件&#xff0c;则输出yes import…

《基于 PySpark 的电影推荐系统分析及问题解决》

以下是一篇关于上述代码的博客文章&#xff1a; 基于PySpark的电影推荐系统实现与分析 在当今数字化时代&#xff0c;个性化推荐系统在各个领域中都发挥着至关重要的作用&#xff0c;尤其是在娱乐行业&#xff0c;如电影推荐。本文将详细介绍如何使用PySpark构建一个简单的电…

每天五分钟深度学习pytorch:批归一化全连接网络完成手写字体识别

本文重点 前面我们学习了普通的全连接神经网络,后面我们学习了带有激活层的全连接神经网络,本文我们继续进一步升级,我们学习带有批归一化的全连接神经网络,批归一化可以加快神经网络的训练速度,减少过拟合,具体它的原理,大家可以看我们的《每天五分钟深度学习》专栏,…

JavaWeb后端开发知识储备1

目录 1.DTO/VO/PO 2.MVC架构/微服务架构 3.JWT令牌流程 4.ThreadLocal 5.接口路径/路径参数 6.自定义注解 1.DTO/VO/PO 1.1 DTO DTO 即 Data Transfer Object—— 数据传输对象&#xff0c;是用于传输数据的对象&#xff0c;通常在服务层与表现层之间传递数据&#xff…