sharding sphere 4.0.0-RC1版本 按年分表实战

2024-05-02 10:18

本文主要是介绍sharding sphere 4.0.0-RC1版本 按年分表实战,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1. sharding sphere 4.0.0-RC1版本 按年分表实战

1.1. 需求

需要对日志表进行按时间划分表,由于用于后台系统,日志量预估不会太大,因此按年划分表

经过我不断的查阅sharding sphere资料和实践,我最后还是决定先建表,再把actual-data-nodes表结点给定下来,为什么这么说?

我纠结的是到底要不要动态创建表,若想要不自己手动每隔几年维护表,我们当然希望能自动创建。但经过我的实践,sharding sphere本身没有提供该功能,但可以通过分片算法实现类中自定义实现,但前提是我们要随时知道要分片表有几个分片,比如log_2019,log_2020,log_2021,只要我能初始化的时候知道分片有几个表以及表名,那么我就不会查询到不存在的表导致报错,反之则容易报错

我们知道mysql可以通过查询information_schema.TABLES来查询存在的表,但是不知道是不是sharding sphere的bug,我用库名加表名查该库它会强制给我改写成我默认的连接库,导致表不存在,根本查不到

所以我退而求其次,下面我列出我的方案,方案采用的版本是4.0.0-RC1

1.2. 引入pom

  1. 先把pom列出来,只给代码不给pom都是耍流氓
         <!-- 分库分表 --><dependency><groupId>org.apache.shardingsphere</groupId><artifactId>sharding-jdbc-spring-boot-starter</artifactId><version>4.0.0-RC1</version></dependency><dependency><groupId>org.apache.shardingsphere</groupId><artifactId>sharding-jdbc-spring-namespace</artifactId><version>4.0.0-RC1</version></dependency>

1.3. application.yml配置

  1. 如下配置,分表最重要的是table-strategy分表策略,sharding-column表示分表字段,当插入查询需要指定哪个分表时,必须带上这个条件,否则可能出错,actual-data-nodes表示你分了哪些表,它有一定语法,如下$->{0..1}表示system_log_2020,system_log_2021两张表,我需要在mysql建好这两张表
spring:shardingsphere:props:sql:show: truedatasource:names: ds0ds0:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://xxxxx:3306/test?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8&allowMultiQueries=trueusername: xxxpassword: xxxsharding:tables:system_log:actual-data-nodes: ds0.system_log_202$->{0..1}table-strategy:standard:sharding-column: createdprecise-algorithm-class-name: com.xxx.platform.system.log.LogShardingAlgorithmrange-algorithm-class-name: com.xxx.platform.system.log.LogShardingAlgorithm

1.4. 分表策略

  1. 最重要的就是LogShardingAlgorithm这个类
import com.google.common.collect.Range;
import lombok.extern.slf4j.Slf4j;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingValue;
import org.apache.shardingsphere.api.sharding.standard.RangeShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.RangeShardingValue;import java.util.ArrayList;
import java.util.Collection;/*** @author: laoliangliang* @description: 日志分片* @create: 2020/1/2 10:19**/
@Slf4j
public class LogShardingAlgorithm implements PreciseShardingAlgorithm, RangeShardingAlgorithm<Integer> {@Overridepublic String doSharding(Collection availableTargetNames, PreciseShardingValue shardingValue) {String target = shardingValue.getValue().toString();return shardingValue.getLogicTableName() + "_" + target.substring(target.lastIndexOf("_") + 1, target.lastIndexOf("_") + 5);}@Overridepublic Collection<String> doSharding(Collection<String> availableTargetNames, RangeShardingValue<Integer> shardingValue) {Collection<String> availables = new ArrayList<>();Range valueRange = shardingValue.getValueRange();for (String target : availableTargetNames) {Integer shardValue = Integer.parseInt(target.substring(target.lastIndexOf("_") + 1, target.lastIndexOf("_") + 5));if (valueRange.hasLowerBound()) {String lowerStr = valueRange.lowerEndpoint().toString();Integer start = Integer.parseInt(lowerStr.substring(0, 4));if (start - shardValue > 0) {continue;}}if (valueRange.hasUpperBound()) {String upperStr = valueRange.upperEndpoint().toString();Integer end = Integer.parseInt(upperStr.substring(0, 4));if (end - shardValue < 0) {continue;}}availables.add(target);}return availables;}
}
  1. 我实现了PreciseShardingAlgorithm, RangeShardingAlgorithm这两个接口,分别表示当created条件为=between时会分别进入这两个方法,用来判断sql语句命中哪个表
  2. 这里要注意,created的><大于小于判断是不起效果的,求范围只能用between,如果我说错了请提醒哦
  3. 接下来调用sql语句我是这样写的
SELECT created,user_name,`action`,id FROM system_log
<where><if test="id!=null and id!=''">and pk_id=#{id}</if><if test="startTime != null and endTime != null">and created BETWEEN #{startTime} and #{endTime}</if>
</where>
order by created desc

1.5. 结果

  1. mybatis插入后日志如下,可以看到mybatis打印的日志表名还是system_log,但实际对应数据库有system_log_2020,system_log_2021两张表,我插入的时间是2020年,所以只插入2020的表
2020-01-07 16:40:28.165 DEBUG 7780 --- [pool-4-thread-1] c.o.p.p.m.S.insertSelective              : ==>  Preparing: INSERT INTO system_log ( type,pk_id,remark,user_name,created,action ) VALUES( ?,?,?,?,?,? ) 
2020-01-07 16:40:28.165 DEBUG 7780 --- [pool-4-thread-1] c.o.p.p.m.S.insertSelective              : ==> Parameters: 1(Integer), 0(Integer), string(String), 15162191629(String), 2020-01-07 16:40:28.161(Timestamp), 内容(String)
2020-01-07 16:40:28.198  INFO 7780 --- [pool-4-thread-1] ShardingSphere-SQL                       : Rule Type: sharding
2020-01-07 16:40:28.198  INFO 7780 --- [pool-4-thread-1] ShardingSphere-SQL                       : Logic SQL: INSERT INTO system_log  ( type,pk_id,remark,user_name,created,action ) VALUES( ?,?,?,?,?,? )
2020-01-07 16:40:28.198  INFO 7780 --- [pool-4-thread-1] ShardingSphere-SQL                       : SQLStatement: InsertStatement(super=DMLStatement(super=AbstractSQLStatement(type=DML, tables=Tables(tables=[Table(name=system_log, alias=Optional.absent())]), routeConditions=Conditions(orCondition=OrCondition(andConditions=[AndCondition(conditions=[Condition(column=Column(name=created, tableName=system_log), operator=EQUAL, compareOperator=null, positionValueMap={}, positionIndexMap={0=4})])])), encryptConditions=Conditions(orCondition=OrCondition(andConditions=[])), sqlTokens=[TableToken(tableName=system_log, quoteCharacter=NONE, schemaNameLength=0), SQLToken(startIndex=24)], parametersIndex=6, logicSQL=INSERT INTO system_log  ( type,pk_id,remark,user_name,created,action ) VALUES( ?,?,?,?,?,? )), deleteStatement=false, updateTableAlias={}, updateColumnValues={}, whereStartIndex=0, whereStopIndex=0, whereParameterStartIndex=0, whereParameterEndIndex=0), columnNames=[type, pk_id, remark, user_name, created, action], values=[InsertValue(columnValues=[org.apache.shardingsphere.core.parse.old.parser.expression.SQLPlaceholderExpression@21625d01, org.apache.shardingsphere.core.parse.old.parser.expression.SQLPlaceholderExpression@34dda176, org.apache.shardingsphere.core.parse.old.parser.expression.SQLPlaceholderExpression@5d631384, org.apache.shardingsphere.core.parse.old.parser.expression.SQLPlaceholderExpression@13cfbf64, org.apache.shardingsphere.core.parse.old.parser.expression.SQLPlaceholderExpression@20f67249, org.apache.shardingsphere.core.parse.old.parser.expression.SQLPlaceholderExpression@79f9b130])])
2020-01-07 16:40:28.198  INFO 7780 --- [pool-4-thread-1] ShardingSphere-SQL                       : Actual SQL: ds0 ::: INSERT INTO system_log_2020   (type, pk_id, remark, user_name, created, action) VALUES (?, ?, ?, ?, ?, ?) ::: [1, 0, string, 15162191629, 2020-01-07 16:40:28.161, 内容]
2020-01-07 16:40:28.210 DEBUG 7780 --- [pool-4-thread-1] c.o.p.p.m.S.insertSelective              : <==    Updates: 1
  1. 如上的查询语句结果也同理,只查2020年

查询参数

{"endTime": "2020-01-10 01:01:01","id": 435,"page": 1,"pageSize": 10,"startTime": "2020-01-01 01:01:01"
}

查询结果

2020-01-07 16:50:49.878 DEBUG 5408 --- [nio-9000-exec-2] c.o.p.p.m.S.getReportLogList             : ==>  Preparing: SELECT created,user_name,`action`,id,remark FROM system_log WHERE pk_id=? and created BETWEEN ? and ? order by created desc LIMIT ? 
2020-01-07 16:50:49.879 DEBUG 5408 --- [nio-9000-exec-2] c.o.p.p.m.S.getReportLogList             : ==> Parameters: 435(Integer), 2020-01-01 01:01:01.0(Timestamp), 2020-01-10 01:01:01.0(Timestamp), 10(Integer)
2020-01-07 16:50:49.891  INFO 5408 --- [nio-9000-exec-2] ShardingSphere-SQL                       : Rule Type: sharding
2020-01-07 16:50:49.891  INFO 5408 --- [nio-9000-exec-2] ShardingSphere-SQL                       : Logic SQL: SELECT created,user_name,`action`,id,remark FROM system_logWHERE  pk_id=?and created BETWEEN ? and ? order by created desc LIMIT ? 
2020-01-07 16:50:49.891  INFO 5408 --- [nio-9000-exec-2] ShardingSphere-SQL                       : SQLStatement: SelectStatement(super=DQLStatement(super=AbstractSQLStatement(type=DQL, tables=Tables(tables=[Table(name=system_log, alias=Optional.absent())]), routeConditions=Conditions(orCondition=OrCondition(andConditions=[AndCondition(conditions=[Condition(column=Column(name=created, tableName=system_log), operator=BETWEEN, compareOperator=null, positionValueMap={}, positionIndexMap={0=1, 1=2})])])), encryptConditions=Conditions(orCondition=OrCondition(andConditions=[])), sqlTokens=[TableToken(tableName=system_log, quoteCharacter=NONE, schemaNameLength=0)], parametersIndex=4, logicSQL=SELECT created,user_name,`action`,id,remark FROM system_logWHERE  pk_id=?and created BETWEEN ? and ? order by created desc LIMIT ? )), containStar=false, firstSelectItemStartIndex=7, selectListStopIndex=42, groupByLastIndex=0, items=[CommonSelectItem(expression=created, alias=Optional.absent()), CommonSelectItem(expression=user_name, alias=Optional.absent()), CommonSelectItem(expression=action, alias=Optional.absent()), CommonSelectItem(expression=id, alias=Optional.absent()), CommonSelectItem(expression=remark, alias=Optional.absent())], groupByItems=[], orderByItems=[OrderItem(owner=Optional.absent(), name=Optional.of(created), orderDirection=DESC, nullOrderDirection=ASC, index=-1, expression=null, alias=Optional.absent())], limit=Limit(offset=null, rowCount=LimitValue(value=-1, index=3, boundOpened=false)), subqueryStatement=null, subqueryStatements=[], subqueryConditions=[])
2020-01-07 16:50:49.891  INFO 5408 --- [nio-9000-exec-2] ShardingSphere-SQL                       : Actual SQL: ds0 ::: SELECT created,user_name,`action`,id,remark FROM system_log_2020WHERE  pk_id=?and created BETWEEN ? and ? order by created desc LIMIT ?  ::: [435, 2020-01-01 01:01:01.0, 2020-01-10 01:01:01.0, 10]
2020-01-07 16:50:49.898 DEBUG 5408 --- [nio-9000-exec-2] c.o.p.p.m.S.getReportLogList             : <==      Total: 2

1.6. 总结

这次主要的碰壁内容就是created的大于小于问题,大于小于触发不了表分片行为,需要特别注意。希望对你有帮助
老梁讲Java

欢迎关注公众号,一起学习进步

这篇关于sharding sphere 4.0.0-RC1版本 按年分表实战的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/954021

相关文章

ONLYOFFICE 8.1 版本桌面编辑器测评

在现代办公环境中,办公软件的重要性不言而喻。从文档处理到电子表格分析,再到演示文稿制作,强大且高效的办公软件工具能够极大提升工作效率。ONLYOFFICE 作为一个功能全面且开源的办公软件套件,一直以来都受到广大用户的关注与喜爱。而其最新发布的 ONLYOFFICE 8.1 版本桌面编辑器,更是带来了诸多改进和新特性。本文将详细评测 ONLYOFFICE 8.1 版本桌面编辑器,探讨其在功能、用户

17.用300行代码手写初体验Spring V1.0版本

1.1.课程目标 1、了解看源码最有效的方式,先猜测后验证,不要一开始就去调试代码。 2、浓缩就是精华,用 300行最简洁的代码 提炼Spring的基本设计思想。 3、掌握Spring框架的基本脉络。 1.2.内容定位 1、 具有1年以上的SpringMVC使用经验。 2、 希望深入了解Spring源码的人群,对 Spring有一个整体的宏观感受。 3、 全程手写实现SpringM

React+TS前台项目实战(十七)-- 全局常用组件Dropdown封装

文章目录 前言Dropdown组件1. 功能分析2. 代码+详细注释3. 使用方式4. 效果展示 总结 前言 今天这篇主要讲全局Dropdown组件封装,可根据UI设计师要求自定义修改。 Dropdown组件 1. 功能分析 (1)通过position属性,可以控制下拉选项的位置 (2)通过传入width属性, 可以自定义下拉选项的宽度 (3)通过传入classN

Visual Studio中,MSBUild版本问题

假如项目规定了MSBUild版本,那么在安装完Visual Studio后,假如带的MSBUild版本与项目要求的版本不符合要求,那么可以把需要的MSBUild添加到系统中,然后即可使用。步骤如下:            假如项目需要使用V12的MSBUild,而安装的Visual Studio带的MSBUild版本为V14。 ①到MSDN下载V12 MSBUild包,把V12包解压到目录(

Pycharm配置conda环境(解决新版本无法识别可执行文件问题)

引言: 很多小伙伴在下载最新版本的pycharm或者更新到最新版本后为项目配置conda环境的时候,发现文件夹目录中无法显示可执行文件(一般为python.exe),以下就是本人遇到该问题后试验和解决该问题的一些方法和思路。 一般遇到该问题的人群有两种,一种是刚入门对pycharm进行conda环境配置的小白(例如我),不熟悉相关环境配置的操作和过程,还有一种是入坑pycharm有段时间的老手

PyTorch模型_trace实战:深入理解与应用

pytorch使用trace模型 1、使用trace生成torchscript模型2、使用trace的模型预测 1、使用trace生成torchscript模型 def save_trace(model, input, save_path):traced_script_model = torch.jit.trace(model, input)<

下载Xcode的历史版本

1.打开链接:https://developer.apple.com/download/more 进入页面 2.在搜索框输入Xcode,回车搜索.如图,找到各种版本Xcode 搜索Xcode 3.双击要下载的Xcode,或者点击前面的+,打开详细.点击下载 下载Xcode 4.接下来就耐心等待下载吧!

Win10用户必看:最好用最稳定的版本在此,值得一试!

在Win10电脑操作中,用户可以根据的需要,下载安装不同的系统版本。现在,许多用户好奇Win10哪个版本最好用最稳定?接下来小编给大家推荐最好用最稳定的Win10版本,这些系统版本经过优化升级,相信会给大家带来最棒的操作体验感,且下载安装步骤非常简单。   推荐一:Windows10 22H2 X64 官方正式版   点击下载:https://www.xitongzhijia.net/wi

最新版本的MySQL的下载和安装(Release: 8.0.12)

1.打开百度搜索【Myql】,或直达官网https://dev.mysql.com/ 2.点选【Download按钮】,跳转到下载页面,拉到底部再点选【Community Download】社区版[免费版]

最新版本的JDK安装和配置(Java SE 10.0.2)

1.废话少说,要么百度JDK,要么直接点传送门http://www.oracle.com/technetwork/java/javase/downloads/index.html。这里需要说的JDK包含JRE,打个比方,JDK就是厨房,包含各种工具,而JRE是运行环境,就是锅。所以下载的话,直接下载最新JDK最好。然后根据你的系统位数选择版本。我的是64bit. 2.点击1的右边中间的【JD