【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")
  )
相关推荐
z06.1 小时前
MySQL索引
数据库·mysql
考虑考虑1 小时前
Posrgresql恢复.backup文件
数据库·后端·postgresql
云祺vinchin1 小时前
中小企业备份软件选型从恢复需求到总体成本评估
数据库·数据备份·中小企业备份·容灾备份软件
Zenova EdgeOS2 小时前
Go 工业边缘错误处理实战:用 errors 构建可追溯错误链
开发语言·数据库·golang
KKKlucifer2 小时前
国内数据安全服务的产品智能化转型:大模型赋能下的技术能力重构分析
大数据·数据库·重构
字节跳动开源3 小时前
OpenViking 上线原生 3D 内容理解模型
数据库·开源
海的透彻4 小时前
dockerfile如何快速构建容器(java服务)
java·开发语言
code2cat5 小时前
Java工具篇之Gradle:用任务图组织构建与交付
java·开发语言·单元测试·gradle
CCIE-Yasuo5 小时前
网络安全-学习数据库-Mysql-2
数据库·学习·mysql
这个DBA有点耶5 小时前
内核级AI与多模融合:AI数据库在海外场景的落地要点
数据库·人工智能·架构