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> {
    
    @Override
    public String doSharding(Collection<String> dataSourceNames, PreciseShardingValue<Long> preciseShardingValue) {
        for(String datasourceName : dataSourceNames){
            
            String value = preciseShardingValue.getValue() % dataSourceNames.size() + "";
            
            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> {
    
    @Override
    public String doSharding(Collection<String> dataSourceNames, PreciseShardingValue<Long> preciseShardingValue) {
        for(String datasourceName : dataSourceNames){
            String value = preciseShardingValue.getValue() % dataSourceNames.size() + "";
            
            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> {
    
    @Override
    public Collection<String> doSharding(Collection<String> dataSourceNames, RangeShardingValue<Long> shardingValue) {
        Set<String> result = new LinkedHashSet<>();
        
        Long lower  = shardingValue.getValueRange().lowerEndpoint();
        
        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> {
    
    @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<>();
        
        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;
    }
    
    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> {
    
    @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;
    }
}