【shardingsphere-jdbc】分表实践

一、背景

博主的一个线上IT项目,由于Oracle单表数据量超过了10亿条,出现线上查询超时,无法正确响应用户请求的问题。因此,计划在现有代码工程 中整合shardingsphere-jdbc组件,对该表进行分表处理,优化用户查询速度。

现有代码工程的技术框架为:SpringBoot+MybatisPlus+Oracle

二、注意事项

  1. 现有代码工程整合shardingsphere-jdbc组件后,发现工程里的所有Mapper统一使用shardingsphere-jdbc,暂未研究指定Mapper使用shardingsphere-jdbc的方式。博主的IT项目功能模块较少,因此整合后对IT项目功能进行了全量回归;
  2. 由于设计按照年份进行分表,但配置项中actual-data-nodes内容是写死,需要在新增分表后修改该配置项内容,或者研究动态修改该配置项的方法。

三、版本号

shardingsphere-jdbc不同版本之间配置方式有差异,博主花费了不少时间编辑配置项的内容,最后使用的shardingsphere-jdbc版本信息如下:

xml 复制代码
<dependency>
    <groupId>org.apache.shardingsphere</groupId>
    <artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId>
    <version>5.2.0</version>
</dependency>

四、配置文件

ini 复制代码
spring.shardingsphere.mode.type=Standalone
spring.shardingsphere.props.sql-show=true
spring.shardingsphere.datasource.names=shard-test
spring.shardingsphere.datasource.shard-test.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.shard-test.driver-class-name=oracle.jdbc.driver.OracleDriver
spring.shardingsphere.datasource.shard-test.jdbc-url=jdbc:oracle:thin:@10.101.30.196:1528/zcgj
spring.shardingsphere.datasource.shard-test.username=zcgj
spring.shardingsphere.datasource.shard-test.password=zcgj@2023poiuy

spring.shardingsphere.rules.sharding.tables.SHARD.table-strategy.standard.sharding-column=create_year #自定义分表字段
spring.shardingsphere.rules.sharding.tables.SHARD.actual-data-nodes=shard-test.SHARD_$->{2020..2025} #自定义表名区间
spring.shardingsphere.rules.sharding.tables.SHARD.table-strategy.standard.sharding-algorithm-name=create-year #自定义分表逻辑命名
spring.shardingsphere.rules.sharding.sharding-algorithms.create-year.type=inline #分表逻辑类型枚举值
spring.shardingsphere.rules.sharding.sharding-algorithms.create-year.props.algorithm-expression=SHARD_${create_year} #分表逻辑

五、分表结果验证

接口验证用例如下,结论在以下注释中:

scss 复制代码
@Test
public void test() {
    // 数据可以按照逻辑,插入到不同create-year的表中
    List<ShardEntity> list = new LinkedList<>();
    for (int k = 2020; k <= 2025; k++) {
        for (int i = 0; i < 500; i++) {
            for (int j = 0; j < 1000; j++) {
                ShardEntity shardEntity = new ShardEntity();
                shardEntity.setId(UUID.randomUUID().toString().replace("-",""));
                shardEntity.setCreateTime(new Date());
                shardEntity.setCreateYear(String.valueOf(k));
                list.add(shardEntity);
            }
            this.shardService.saveBatch(list);
            list.clear();
        }
    }

    // 列表查询数据范围涉及多张分表时,list接口返回的是各个分表的汇总数据,如下返回了20条数据,而非10条
    LambdaQueryWrapper<ShardEntity> queryWrapper = Wrappers.lambdaQuery();
    queryWrapper.in(ShardEntity::getCreateYear, new String[]{"2024", "2025"})
            .orderByDesc(ShardEntity::getCreateTime) // 按时间降序排序
            .apply("ROWNUM <= 10"); // 限制只返回第一条记录
    List<ShardEntity> shards = this.shardService.list(queryWrapper);
    log.info("shards=[{}]", shards);

    // 分页查询数据范围涉及多张分表时,page接口返回条数为10条,优先返回SHARD_2024表中的内容
    queryWrapper = Wrappers.lambdaQuery();
    queryWrapper.in(ShardEntity::getCreateYear, new String[]{"2024", "2025"})
            .orderByDesc(ShardEntity::getCreateTime); // 按时间降序排序
    Page page = new Page();
    page.setCurrent(1);
    page.setSize(10);
    Page<ShardEntity> shardEntityPage = this.shardService.page(page, queryWrapper);
    log.info("shardEntityPage=[{}]", shardEntityPage);
}

附:建表语句

less 复制代码
CREATE TABLE "SHARD_2020" 
   (	"ID" VARCHAR2(32), 
	"REQ_ID" VARCHAR2(64), 
	"REQ_SOURCE" VARCHAR2(32), 
	"ERRCODE" NUMBER(16,0), 
	"ERRMSG" VARCHAR2(1024), 
	"CREATE_TIME" DATE DEFAULT SYSDATE, 
	"UPDATE_TIME" DATE DEFAULT SYSDATE, 
	"CREATE_USER" VARCHAR2(16), 
	"UPDATE_USER" VARCHAR2(16), 
	"CREATE_YEAR" VARCHAR2(8), 
	PRIMARY KEY ("ID")
  )
相关推荐
Boilermaker19923 分钟前
【Redis】哨兵与对脑裂的情况分析
数据库·redis·缓存
Kay_Liang7 分钟前
大语言模型如何精准调用函数—— Function Calling 系统笔记
java·大数据·spring boot·笔记·ai·langchain·tools
橘 日向7 分钟前
admin二维码字符过长导致显示失败问题
数据库·oracle
啊吧怪不啊吧24 分钟前
SQL之参数类型讲解
数据库·sql
自由的疯24 分钟前
Java 如何学习Docker
java·后端·架构
自由的疯25 分钟前
Java Docker本地部署
java·后端·架构
007php00727 分钟前
猿辅导Java面试真实经历与深度总结(二)
java·开发语言·python·计算机网络·面试·职场和发展·golang
摇滚侠30 分钟前
Spring Boot 3零基础教程,WEB 开发 内容协商机制 笔记34
java·spring boot·笔记·缓存
一勺菠萝丶30 分钟前
在 macOS 上用 Docker 为 Java 后端 & 常见开发需求搭建完整服务(详尽教程)
java·macos·docker
顾漂亮36 分钟前
JVM底层攻坚
java·jvm·spring