sharding-jdbc分片策略

一、在上一节中提到了分库分表的策略。分库策略算法GroupIDAndCollectTimeDBShardingAlgorithm和分表策略算法CollectTimeYYYYMMDDTBShardingAlgorithm

     分片策略算法有很多,但是一般的都是需要自定义,dangdangwang提供了最顶层的实现,但是具体的算法需要我们自己来写。

     这里有两个自定义的算法,单分片算法和多分片算法,单分片算法是多分片算法的一种简单形式,所以完全可以用多分片算法代替单分片算法,下面两种形式是等价的。

newTableShardingStrategy("order_id",newSingleKeyShardingAlgorithm()))newTableShardingStrategy(Arrays.asList("order_id"),newMultiKeyShardingAlgorithm()))

同时在算法内部,dosharding等方法的shardingvalue入参根据使用算法类型不同而不同,单分片算法方public String doEqualSharding(final Collection<String> dataSourceNames,final ShardingValue<Integer> shardingValue)

多分片算法public Collection<String>doSharding(final Collection<String> availableTargetNames,final Collection<ShardingValue<?>> shardingValues)

根据数据源策略和表策略,单分片与多分片,这两种组合一共产生了4中可供实现的分片算法的接

  • 单分片键数据源分片算法SingleKeyDatabaseShardingAlgorithm
  • 单分片表分片算法SingleKeyTableShardingAlgorithm
  • 多分片键数据源分片算法MultipleKeyDatabaseShardingAlgorithm
  • 多分片表分片算法MultipleKeyTableShardingAlgorithm

 单分片建算法需要实现三个方法,下面以单分片建数据源分片算法举例:

@Override public String doEqualSharding(final Collection<String> availableTargetNames,final ShardingValue<Integer> shardingValue) @Override public Collection<String>doInSharding(final Collection<String> availableTargetNames,final ShardingValue<Integer> shardingValue) @Override public Collection<String>doBetweenSharding(final Collection<String> availableTargetNames,final ShardingValue<Integer> shardingValue)

 这三种算法作用如下 - doEqualSharding在WHERE使用=作为条件分片键。算法中使用shardingValue.getValue()获取等=后的值 -doInSharding在WHERE使用IN作为条件分片键。算法中使用shardingValue.getValues()获取IN后的值 - doBetweenSharding在WHERE使用BETWEEN作为条件分片键。算法中使用shardingValue.getValueRange()获取BETWEEN后的值

 多分片建算法适用于比较复杂的场景,为了提高灵活性故只提供了一个方法实现

public Collection<String>doSharding(final Collection<String> availableTargetNames,final Collection<ShardingValue<?>> shardingValues)

算法实现的时候根据shardingValue.getType来获取条件是= .IN还是between

举个例:

db0 ├── t_order_00 user_id以a偶数 order_id为偶数 ├── t_order_01 user_id以a偶数 order_id为奇数 ├── t_order_10 user_id以b奇数 order_id为偶数 └── t_order_11 user_id以b奇数 order_id为奇数

 

public final class MultipleKeysModuloTableShardingAlgorithm implements MultipleKeysTableShardingAlgorithm {
    @Override
    public Collection<String> doSharding(final Collection<String> availableTargetNames, final Collection<ShardingValue<?>> shardingValues) {
        Set<Integer> orderIdValueSet = getShardingValue(shardingValues, "order_id");
        Set<Integer> userIdValueSet = getShardingValue(shardingValues, "user_id");
        List<String> result = new ArrayList<>();
        /*
        userIdValueSet[10,11] + orderIdValueSet[101,102] => valueResult[[10,101],[10,102],[11,101],[11,102]]
         */
        Set<List<Integer>> valueResult = Sets.cartesianProduct(userIdValueSet, orderIdValueSet);
        for (List<Integer> value : valueResult) {
            String suffix = Joiner.on("").join(value.get(0) % 2, value.get(1) % 2);
            for (String tableName : availableTargetNames) {
                if (tableName.endsWith(suffix)) {
                    result.add(tableName);
                }
            }
        }
        return result;
    }
    
    private Set<Integer> getShardingValue(final Collection<ShardingValue<?>> shardingValues, final String shardingKey) {
        Set<Integer> valueSet = new HashSet<>();
        ShardingValue<Integer> shardingValue = null;
        for (ShardingValue<?> each : shardingValues) {
            if (each.getColumnName().equals(shardingKey)) {
                shardingValue = (ShardingValue<Integer>) each;
                break;
            }
        }
        if (null == shardingValue) {
            return valueSet;
        }
        switch (shardingValue.getType()) {
            case SINGLE:
                valueSet.add(shardingValue.getValue());
                break;
            case LIST:
                valueSet.addAll(shardingValue.getValues());
                break;
            case RANGE:
                for (Integer i = shardingValue.getValueRange().lowerEndpoint(); i <= shardingValue.getValueRange().upperEndpoint(); i++) {
                    valueSet.add(i);
                }
                break;
            default:
                throw new UnsupportedOperationException();
        }
        return valueSet;
    }
}

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
课程简介 随着互联网的发展,软件的规模在逐渐变大,用关系型数据库如何存储和处理大规模的业务数据成为企业面临的挑战, 关系型数据库作为OLTP(联机事务处理过程)系统的首选毋庸置疑,但是关系型数据面对大规模数据的处理有其先天的不足,比如单表存储上千万数据时便会出现不同程度的处理速度缓慢问题,如何解决?分库分表技术就是为了解决由于数据量过大而导致数据库性能降低的问题,将原来独立的数据库拆分成若干数据库组成 ,将数据大表拆分成若干数据表组成,使得单一数据库、单一数据表的数据量变小,从而达到提升数据库性能的目的。本课程将系统的讲解分库分表技术。 课程价值 分库分表技术是为解决关系型数据库存储和处理大规模数据的问题,主要应用于OLTP系统,它与应用于OLAP(联机分析处理)的大数据技术有不同的应用场景,本课程本着从解决生产实际问题出发,讲授分库分表技术的解决方案,包括:垂直分库、垂直分表、水平分库、水平分表、读写分离,涵盖了分库分表的各种方案,并且深入讲解Sharding-JDBC框架的原理及使用方法,通过学习本课程可以快速应用到生产实践中。 课程优势 本课程不仅讲解多种有效的分库分表的解决方案,还深入讲解了Sharding-JDBC框架的原理和使用方法,Sharding-JDBC是一套轻量级的对代码零侵入的框架,在生产中有广泛的使用。本课程从思想原理、技术框架、案例实操三个方面去学习,可以快速的将分库分表技术应用到生产实践中,解决大数据存储与处理的问题。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值