在前面一篇《跟我学ShardingSphere之SpringBoot + ShardingJDBC分库》我们介绍了如何利用ShardingJDBC进行分库,用到了inline行表达式分片策略,ShardingSphere还有其他几种分片策略,下面我们来介绍一下

分片键

用于分片的字段,是将数据库或表拆分的字段,比如,我可以使用user_id作为分片键将用户数据分到不同的表中,这里的user_id就是分片键,除了这种单字段分片,ShardingSphere还支持多个分片字段。SQL中如果没有分片字段,将执行全路由,也就是会把SQL发送到所有的数据分片上执行,性能较差。

分片算法

分片算法描述的是如何进行分片,需要结合分片键使用,比如我需要使用user_id对2取模进行分表,那么这里取模就是分片算法,ShardingShpere支持>、<、=、IN和Between分片。这些分片算法需要根据实际的业务开发,ShardingSphere没有默认的分片算法,所以你得根据自己的业务来开发自己的分片算法,不过也挺简单的,ShardingSphere已经预留好了对应的接口,你实现对应的接口就好了

目前ShardingSphere将常用的分片算法进行抽象,定义了四种分片算法

1、精确分片算法

对应PreciseShardingAlgorithm,用于处理使用单一键作为分片键的=与IN进行分片的场景。需要配合StandardShardingStrategy使用。

2、范围分片算法

对应RangeShardingAlgorithm,用于处理使用单一键作为分片键的BETWEEN AND、>、<、>=、<=进行分片的场景。需要配合StandardShardingStrategy使用。

3、复合分片算法

对应ComplexKeysShardingAlgorithm,用于处理使用多键作为分片键进行分片的场景,包含多个分片键的逻辑较复杂,需要应用开发者自行处理其中的复杂度。需要配合ComplexShardingStrategy使用。

4、Hint分片算法

对应HintShardingAlgorithm,用于处理使用Hint行分片的场景。需要配合HintShardingStrategy使用

分片策略

包含分片键和分片算法,由于分片算法的独立性,将其独立抽离。真正可用于分片操作的是分片键 + 分片算法,也就是分片策略。目前提供5种分片策略

1、标准分片策略

对应StandardShardingStrategy。提供对SQL语句中的=, >, <, >=, <=, IN和BETWEEN AND的分片操作支持。StandardShardingStrategy只支持单分片键,提供PreciseShardingAlgorithm和RangeShardingAlgorithm两个分片算法。PreciseShardingAlgorithm是必选的,用于处理=和IN的分片。RangeShardingAlgorithm是可选的,用于处理BETWEEN AND, >, <, >=, <=分片,如果不配置RangeShardingAlgorithm,SQL中的BETWEEN AND将按照全库路由处理。

2、复合分片策略

对应ComplexShardingStrategy。复合分片策略。提供对SQL语句中的=, >, <, >=, <=, IN和BETWEEN AND的分片操作支持。ComplexShardingStrategy支持多分片键,由于多分片键之间的关系复杂,因此并未进行过多的封装,而是直接将分片键值组合以及分片操作符透传至分片算法,完全由应用开发者实现,提供最大的灵活度。

3、行表达式分片策略

对应InlineShardingStrategy。使用Groovy的表达式,提供对SQL语句中的=和IN的分片操作支持,只支持单分片键。对于简单的分片算法,可以通过简单的配置使用,从而避免繁琐的Java代码开发,如: t_user_$->{u_id % 8} 表示t_user表根据u_id模8,而分成8张表,表名称为t_user_0到t_user_7。

4、Hint分片策略

对应HintShardingStrategy。通过Hint指定分片值而非从SQL中提取分片值的方式进行分片的策略

5、不分片策略

对应NoneShardingStrategy。不分片的策略。

分片示例

我们还是通过一个分表的示例来演示一下,如何根据自己的需求来开发自己的分片算法

需求:业务上存在多个分支机构,需要将不同分支的客户拆分到不同的表

分析:通过需求可知,这是个单分片的需求,我们选择标准分片就可以满足需求

1、先建表

CREATE TABLE `tb_cust` (`cust_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '用户ID',`cust_name` varchar(20) NOT NULL COMMENT '用户名称',`branch_id` char(3) NOT NULL COMMENT '分公司',`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',PRIMARY KEY (`cust_id`)
) ENGINE=InnoDB AUTO_INCREMENT=202 DEFAULT CHARSET=utf8 COMMENT='客户信息表';

按不同的分支机构建不同的表

从表名可以看出来,我们有fc5、fdg、fdm、fdw这几个分支机构

2、分片算法

标准分片策略需要实现PreciseShardingAlgorithm接口

/*** 精确分片算法(可用于分库、分表)* 公众号【Java天堂】*/
public class BranchPreciseShardingAlgorithm implements PreciseShardingAlgorithm<String> {@Overridepublic String doSharding(Collection<String> shardingNameList, PreciseShardingValue<String> preciseShardingValue) {String key = preciseShardingValue.getValue();//遍历所有的数据分片,与分片键(key)比较,匹配就返回当前数据分片for(String shardingName : shardingNameList){if(shardingName.endsWith(key.toLowerCase())){return shardingName;}}throw new IllegalArgumentException();}
}

3、分片策略配置

server:port: 8090spring:main:allow-bean-definition-overriding: trueshardingsphere:datasource:names: testdb0,testdb1testdb0:type: com.zaxxer.hikari.HikariDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverjdbc-url: jdbc:mysql://localhost:3306/testdb0?useUnicode=true&characterEncoding=utf-8username: rootpassword: 123456testdb1:type: com.zaxxer.hikari.HikariDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverjdbc-url: jdbc:mysql://localhost:3306/testdb1?useUnicode=true&characterEncoding=utf-8username: rootpassword: 123456# 分库、分表配置sharding:tables:tb_cust:actual-data-nodes: testdb0.tb_cust_$->{['fdg','fc5','fdw','fdm']}# 分表配置table-strategy:standard:sharding-column: branch_idprecise-algorithm-class-name: com.kxg.shardingRule.BranchPreciseShardingAlgorithmprops:sql.show: true

从上面的配置可以看出来,我们分表的策略不再是inline,而是换成standard,表示标准分片策略

分片策略也换成了我们自己写的分片算法:BranchPreciseShardingAlgorithm

@Data
@TableName("tb_cust")
public class Cust {private Long custId;private String custName;private String branchId;
}
public interface CustMapper extends BaseMapper<Cust> {}
@Service
public class CustService {@Autowiredprivate CustMapper custMapper;public void insert(Cust cust){int count = custMapper.insert(cust);System.out.println("insert count:" + count);}public Cust getCust(Long custId){return custMapper.selectById(custId);}
}
@RestController
public class CustController {@Autowiredprivate CustService custService;@RequestMapping("/cust/add")public String addUser(@RequestBody Cust cust){custService.insert(cust);return "ok";}@RequestMapping("/cust/get")@ResponseBodypublic Cust getUser(Long custId){return custService.getCust(custId);}
}

启动程序,可以看到如下打印:

tables:tb_cust:actualDataNodes: testdb0.tb_cust_$->{['fdg','fc5','fdw','fdm']}logicTable: tb_custtableStrategy:standard:preciseAlgorithmClassName: com.kxg.shardingRule.BranchPreciseShardingAlgorithmshardingColumn: branch_id

表示已经加载配置成功

我们试着添加两个Cust信息,如下


我们可以看到控制台打印的SQL语句:

Logic SQL: INSERT INTO tb_cust  ( cust_id,cust_name,branch_id )  VALUES  ( ?,?,? )
Actual SQL: testdb0 ::: INSERT INTO tb_cust_fdg  ( cust_id,cust_name,branch_id )  VALUES  (?, ?, ?) ::: [1, 客户-FDG, FDG]Logic SQL: INSERT INTO tb_cust  ( cust_id,cust_name,branch_id )  VALUES  ( ?,?,? )
Actual SQL: testdb0 ::: INSERT INTO tb_cust_fc5  ( cust_id,cust_name,branch_id )  VALUES  (?, ?, ?) ::: [2, 客户-FC5, FC5]

从执行的SQL可以看到,是根据我们的预期进行分表操作的,下面去数据库对应的表查看一下对应的数据是不是正确插入

可以看到,两次的数据根据不同的branchId字段插入到不同的表中,达到了根据branchId分表的目的

如果感觉对你有些帮忙,请收藏好,你的关注和点赞是对我最大的鼓励!
如果想跟我一起学习,坚信技术改变世界,请关注【Java天堂】公众号,我会定期分享自己的学习成果,第一时间推送给您

跟我学ShardingSphere之数据分片策略相关推荐

  1. Java基础之超大集合数据分片策略

    超大集合数据分片策略 文章目录 超大集合数据分片策略 一.实际场景 二.解决思路 三.实现方法 3.1 Guava 3.2 Common-Collections 3.3 手动编码实现 四.总结 一.实 ...

  2. Greenplum数据库数据分片策略Hash分布——GUC gp_use_legacy_hashops

    GUC系统参数gp_use_legacy_hashops可以控制建立列分布表时使用传统的哈希算法还是新的哈希算法.新的哈希算法如Greenplum数据库Hash分布--计算哈希值和映射segment文 ...

  3. sharding-jdbc 分库分表的 4种分片策略,还蛮简单的

    上文<快速入门分库分表中间件 Sharding-JDBC (必修课)>中介绍了 sharding-jdbc 的基础概念,还搭建了一个简单的数据分片案例,但实际开发场景中要远比这复杂的多,我 ...

  4. 算法高级(19)-不得不懂的Redis Cluster数据分片机制

    亲爱的同学们,你是否使用过Redis集群呢?那Redis集群的原理又是什么呢?记住下面两句话: Redis Sentinal着眼于高可用,在master宕机时会自动将slave提升为master,继续 ...

  5. 国产分布式数据库StarDB核心技术 一:内核分解之数据分片

    前言 作者:徐力权(StarDB架构师) 数据分片是分布式数据库主要特性之一,好的分片设计能让数据库服务器资源得到最大化利用,提升系统吞吐量.灵活的分片策略实现是StarDB的重要特性之一,StarD ...

  6. ICDE 2022 | Apache ShardingSphere: 一个功能全面和可插拔的数据分片平台(附论文)

    相信大家在网上抢购时遇到过网页无法正常访问的情况,一部分原因可能是数据库无法很好地应对不断增加的并发访问.如何有效地解决数据库现有的这些缺陷呢?数据分片是一个可选的方案.本篇文章将为大家解读由重庆大学 ...

  7. ShardingSphere(八) 分库分表的多种分片策略

    在之前文章<ShardingSphere(二) 水平分表配置搭建,实现分表写入读取>中,我们介绍了数据库的水平分表配置,在文章中只介绍了最简单的行表达式分表配置方式,但往往在实际中我们的业 ...

  8. shardingsphere 分片策略_ShardingSphere系列(二) 分片策略

    本文章适用于初学者demo:或概念理解中策略都在git中打好了tag想要学习那种策略仔细阅读redme即可: 具体代码与明细见:https://github.com/ssy-githup/shardi ...

  9. sharding-jdbc分库分表的 4种分片策略

    如果我一部分表做了分库分表,另一部分未做分库分表的表怎么处理?怎么才能正常访问? 这是一个比较典型的问题,我们知道分库分表是针对某些数据量持续大幅增长的表,比如用户表.订单表等,而不是一刀切将全部表都 ...

最新文章

  1. nginx的HTTP模块编写
  2. HTTP状态码--含义
  3. 如何在WhatsApp中将群聊静音
  4. php访问日记在哪,nginx访问日志在哪里
  5. 以太坊2.0存款合约地址余额28.87万ETH,进度达55%
  6. Serial Interface之I2C:关于DS1624 2线通信SDA保持时间的说明
  7. XJOI 3877 红蓝字符串
  8. 华三服务器bios中查看硬盘,H3C服务器升级BIOS
  9. 复变函数在计算机科学中的应用,051复变函数与实变函数
  10. 基于STM32的智能电子药盒设计
  11. 网络设备:中继器、集线器、网桥、交换机、路由器、网关的超全总结
  12. 《Python编程:从入门到实践》练习16-2:比较锡特卡和死亡谷的温度
  13. 利用STL中的vector实现“有向有权图”的邻接表表示
  14. c语言 main()可否省略,main函数中省略返回语句
  15. H.265及最新芯片模组技术现状和研究方向
  16. linux最大的账户,Linux系统账户安全
  17. 将一串数字转为大写人民币形式
  18. vue3中使用tsx
  19. 人活到极致,一定是素与简
  20. 500 推荐一波高质量的公众号,都是值得大家关注的优质号!

热门文章

  1. html矢量图 SVG VML 介绍
  2. MODBUS通讯详解(博客园)
  3. 【Redis之ZSet类型的详解ZSet类型中常用命令的实践】
  4. 关于PL/SQL我写了一份从0到1的入门教程
  5. 218 扑克牌(数学期望)
  6. VUE环境搭建和项目创建-win平台
  7. 【OpenCV】cv::Mat位深和通道,CV_8UC1等
  8. Photoshop 技能167个(学完它,你可以去相馆做高级设计师了)
  9. WiFi未来发展趋势 你知道吗?
  10. Odoo11入门请假单模块学习教程源码