跟我学ShardingSphere之数据分片策略
在前面一篇《跟我学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之数据分片策略相关推荐
- Java基础之超大集合数据分片策略
超大集合数据分片策略 文章目录 超大集合数据分片策略 一.实际场景 二.解决思路 三.实现方法 3.1 Guava 3.2 Common-Collections 3.3 手动编码实现 四.总结 一.实 ...
- Greenplum数据库数据分片策略Hash分布——GUC gp_use_legacy_hashops
GUC系统参数gp_use_legacy_hashops可以控制建立列分布表时使用传统的哈希算法还是新的哈希算法.新的哈希算法如Greenplum数据库Hash分布--计算哈希值和映射segment文 ...
- sharding-jdbc 分库分表的 4种分片策略,还蛮简单的
上文<快速入门分库分表中间件 Sharding-JDBC (必修课)>中介绍了 sharding-jdbc 的基础概念,还搭建了一个简单的数据分片案例,但实际开发场景中要远比这复杂的多,我 ...
- 算法高级(19)-不得不懂的Redis Cluster数据分片机制
亲爱的同学们,你是否使用过Redis集群呢?那Redis集群的原理又是什么呢?记住下面两句话: Redis Sentinal着眼于高可用,在master宕机时会自动将slave提升为master,继续 ...
- 国产分布式数据库StarDB核心技术 一:内核分解之数据分片
前言 作者:徐力权(StarDB架构师) 数据分片是分布式数据库主要特性之一,好的分片设计能让数据库服务器资源得到最大化利用,提升系统吞吐量.灵活的分片策略实现是StarDB的重要特性之一,StarD ...
- ICDE 2022 | Apache ShardingSphere: 一个功能全面和可插拔的数据分片平台(附论文)
相信大家在网上抢购时遇到过网页无法正常访问的情况,一部分原因可能是数据库无法很好地应对不断增加的并发访问.如何有效地解决数据库现有的这些缺陷呢?数据分片是一个可选的方案.本篇文章将为大家解读由重庆大学 ...
- ShardingSphere(八) 分库分表的多种分片策略
在之前文章<ShardingSphere(二) 水平分表配置搭建,实现分表写入读取>中,我们介绍了数据库的水平分表配置,在文章中只介绍了最简单的行表达式分表配置方式,但往往在实际中我们的业 ...
- shardingsphere 分片策略_ShardingSphere系列(二) 分片策略
本文章适用于初学者demo:或概念理解中策略都在git中打好了tag想要学习那种策略仔细阅读redme即可: 具体代码与明细见:https://github.com/ssy-githup/shardi ...
- sharding-jdbc分库分表的 4种分片策略
如果我一部分表做了分库分表,另一部分未做分库分表的表怎么处理?怎么才能正常访问? 这是一个比较典型的问题,我们知道分库分表是针对某些数据量持续大幅增长的表,比如用户表.订单表等,而不是一刀切将全部表都 ...
最新文章
- nginx的HTTP模块编写
- HTTP状态码--含义
- 如何在WhatsApp中将群聊静音
- php访问日记在哪,nginx访问日志在哪里
- 以太坊2.0存款合约地址余额28.87万ETH,进度达55%
- Serial Interface之I2C:关于DS1624 2线通信SDA保持时间的说明
- XJOI 3877 红蓝字符串
- 华三服务器bios中查看硬盘,H3C服务器升级BIOS
- 复变函数在计算机科学中的应用,051复变函数与实变函数
- 基于STM32的智能电子药盒设计
- 网络设备:中继器、集线器、网桥、交换机、路由器、网关的超全总结
- 《Python编程:从入门到实践》练习16-2:比较锡特卡和死亡谷的温度
- 利用STL中的vector实现“有向有权图”的邻接表表示
- c语言 main()可否省略,main函数中省略返回语句
- H.265及最新芯片模组技术现状和研究方向
- linux最大的账户,Linux系统账户安全
- 将一串数字转为大写人民币形式
- vue3中使用tsx
- 人活到极致,一定是素与简
- 500 推荐一波高质量的公众号,都是值得大家关注的优质号!