complex复合分片算法配置分库分表

经过上一篇 通过SPI实现range查询策略 实现了范围查询之后,那么在本文的开始之前,我在范围查询测试方法当中在加一个条件,来看看查询的结果如何,添加一个 goods_id 查询条件:

image-20211217144236579

@Test
void getOrderBetween() {
    QueryWrapper<Order> qw = new QueryWrapper<>();
    qw.between("tid", 676006592218402816L, 676006593883541505L);
    qw.eq("goods_id", 1005);
    this.orderMapper.selectList(qw).forEach(System.out::println);
}

image-20211217144218722

通过观察运行结果发现,对所有的库和所有的表都进行了查询,其实在我添加了 goods_id 之后是可以精确到某一个库当中的某一张表的,那么如果想要在这种情况下,实现精确的查询,那么就需要用到本文当中所介绍的复合分片算法来进行实现,那么编写套路和之前通过 SPI 扩展 stand 算法差不多。

概述

复合分片策略支持对多个分片健操作

添加配置

image-20211217171327357

# 配置分表策略 主键+分片算法
spring.shardingsphere.rules.sharding.tables.t_order.table-strategy.complex.sharding-columns=tid, goods_id
spring.shardingsphere.rules.sharding.tables.t_order.table-strategy.complex.sharding-algorithm-name=complex-table
spring.shardingsphere.rules.sharding.sharding-algorithms.complex-table.type=COMPLEX_TEST_TAB
# 配置分库策略  主键+分片算法
spring.shardingsphere.rules.sharding.tables.t_order.database-strategy.complex.sharding-columns=tid, goods_id
spring.shardingsphere.rules.sharding.tables.t_order.database-strategy.complex.sharding-algorithm-name=complex-db
spring.shardingsphere.rules.sharding.sharding-algorithms.complex-db.type=COMPLEX_TEST_DB

创建算法实现

image-20211217153040194

DbComplexShardingAlgorithm.java

/**
 * @author BNTang
 * @program ShardingSpherePro
 * @date Created in 2021/12/17 017 15:28
 * @description
 **/
public class DbComplexShardingAlgorithm implements ComplexKeysShardingAlgorithm<Long> {
    @Override
    public Collection<String> doSharding(Collection<String> collection, ComplexKeysShardingValue<Long> complexKeysShardingValue) {
        return null;
    }

    @Override
    public void init() {

    }

    @Override
    public String getType() {
        return null;
    }
}

TableComplexShardingAlgorithm.java

/**
 * @author BNTang
 * @program ShardingSpherePro
 * @date Created in 2021/12/17 017 15:28
 * @description
 **/
public class TableComplexShardingAlgorithm implements ComplexKeysShardingAlgorithm<Long> {
    @Override
    public Collection<String> doSharding(Collection<String> collection, ComplexKeysShardingValue<Long> complexKeysShardingValue) {
        return null;
    }

    @Override
    public void init() {

    }

    @Override
    public String getType() {
        return null;
    }
}

在之前我们 stand 实现的是 StandardShardingAlgorithm 那么 complex 实现的为 ComplexKeysShardingAlgorithm,然后就可以与 stand 一样在覆盖的方法当中编写你自己的算法逻辑即可,博主的算法实现逻辑如下:

DbComplexShardingAlgorithm.java

/**
 * @author BNTang
 * @program ShardingSpherePro
 * @date Created in 2021/12/17 017 15:28
 * @description
 **/
public class DbComplexShardingAlgorithm implements ComplexKeysShardingAlgorithm<Long> {
    @Override
    public Collection<String> doSharding(Collection<String> collection,
                                         ComplexKeysShardingValue<Long> complexKeysShardingValue) {
        /*tid的范围查询
        Range<Long> tidRange = complexKeysShardingValue.getColumnNameAndRangeValuesMap().get("tid");
        如果是tid的范围查询,则返回对应的库名*/
        Collection<Long> goodsIds = complexKeysShardingValue.getColumnNameAndShardingValuesMap().get("goods_id");

        // 如果是goods_id的范围查询,则返回对应的库名
        if (null != goodsIds) {
            return goodsIds.stream()
                    .map(goodsId -> {
                        BigInteger num = BigInteger.valueOf(goodsId).mod(new BigInteger("2"));
                        num = num.add(new BigInteger("1"));
                        return "shardingspheredb" + num;
                    })
                    .collect(Collectors.toList());
        }
        return collection;
    }

    @Override
    public void init() {

    }

    @Override
    public String getType() {
        return "COMPLEX_TEST_DB";
    }
}

TableComplexShardingAlgorithm.java

/**
 * @author BNTang
 * @program ShardingSpherePro
 * @date Created in 2021/12/17 017 15:28
 * @description
 **/
public class TableComplexShardingAlgorithm implements ComplexKeysShardingAlgorithm<Long> {
    @Override
    public Collection<String> doSharding(Collection<String> collection,
                                         ComplexKeysShardingValue<Long> complexKeysShardingValue) {
        /*
        tid的范围查询
        Range<Long> tidRange = complexKeysShardingValue.getColumnNameAndRangeValuesMap().get("tid");
        如果是tid的范围查询,则返回对应的库名
        */
        Collection<Long> goodsIds = complexKeysShardingValue.getColumnNameAndShardingValuesMap().get("goods_id");

        // 如果是goods_id的范围查询,则返回对应的库名
        if (null != goodsIds) {
            return goodsIds.stream()
                    .map(goodsId -> {
                        BigInteger num = BigInteger.valueOf(goodsId).mod(new BigInteger("2"));
                        return complexKeysShardingValue.getLogicTableName() + "_" + num;
                    })
                    .collect(Collectors.toList());
        }
        return collection;
    }

    @Override
    public void init() {

    }

    @Override
    public String getType() {
        return "COMPLEX_TEST_TAB";
    }
}

修改 SPI 文件添加算法类的相对路径:

image-20211217171517055

测试

再次运行之前的范围查询带了 goods_id 的查询,运行结果如下,发现,已经成为了精确的查询,查询的库为 shardingspheredb1 当中的 t_order_0 的真实表:

image-20211217171613314

然后再将 goods_id 去掉进行查询,走的就是博主配置的全库全表如下:

image-20211217171937351

posted @   BNTang  阅读(671)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具
点击右上角即可分享
微信分享提示