使用Shardingsphere根据时间完成分表

配置依赖包

 <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <spring.boot.version>2.7.17</spring.boot.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
            <version>${spring.boot.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>${spring.boot.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <version>${spring.boot.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.28</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.19</version>
        </dependency>
        <dependency>
            <groupId>org.apache.shardingsphere</groupId>
            <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
            <version>4.1.1</version>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.3.2</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.26</version>
        </dependency>

        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.25</version>
        </dependency>
    </dependencies>

增加mybatisplus和shardingsphere配置

server:
  port: 8080
spring:
  main:
    allow-bean-definition-overriding: true
  shardingsphere:
    #配置分库的数据源
    datasource:
      #配置数据源名称
      names: db0
      db0:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8&useSSL=false&autoReconnect=true&rewriteBatchedStatements=true
        username: root
        password: 123456
    props:
      sql:
        show: true #控制台打印sql 方便观察
    sharding:
      tables:
        #要进行分片的表名称
        trace:
          #生成主键
          key-generator:
            #生成主键的列
            column: id
            #生成主键的策略
            type: SNOWFLAKE
          #分片策略
          actual-data-nodes: db0.trace_$->{2401..2912}
          table-strategy: #表分片策略
            standard:
             sharding-column: trace_time
             precise-algorithm-class-name: com.tom.configuration.TraceShardingAlgorithm
             range-algorithm-class-name: com.tom.configuration.TraceRangeShardingAlgorithm

#mybatis-plus
mybatis-plus:
  configuration:
    #驼峰
    map-underscore-to-camel-case: true
  global-config:
    #逻辑删除
    db-config:
      logic-delete-value: true
      logic-not-delete-value: false
  mapper-locations: classpath:mapper/*.xml
  type-handlers-package: com.tom.typehandler

只需要注意上面的precise-algorithm-class-name和range-algorithm-class-name两个策略,主要是对分表键的等值和范围查询

import cn.hutool.core.date.DateUtil;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingValue;

import java.time.LocalDateTime;
import java.util.Collection;

/**
 * @Description
 *
 * @Date 2024/4/30 13:51
 * @Author tom
 **/
public class TraceShardingAlgorithm implements PreciseShardingAlgorithm<LocalDateTime> {

    @Override
    public String doSharding(Collection<String> collection, PreciseShardingValue<LocalDateTime> preciseShardingValue) {
        String timeStr = DateUtil.formatLocalDateTime(preciseShardingValue.getValue());
        String year = timeStr.substring(2, 4);
        String month = timeStr.substring(5, 7);
        String tableSuffix = year + month;
        for (String s : collection) {
            if (s.contains(tableSuffix)){
                return s;
            }
        }
        return null;
    }
}

import cn.hutool.core.date.DateUtil;
import com.google.common.collect.Range;
import org.apache.shardingsphere.api.sharding.standard.RangeShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.RangeShardingValue;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * @Description
 *
 * @Date 2024/4/30 14:18
 * @Author tom
 **/
public class TraceRangeShardingAlgorithm implements RangeShardingAlgorithm<LocalDateTime> {
    @Override
    public Collection<String> doSharding(Collection<String> collection, RangeShardingValue<LocalDateTime> rangeShardingValue) {

        Range<LocalDateTime> valueRange = rangeShardingValue.getValueRange();
        LocalDateTime lowerEndpoint = valueRange.lowerEndpoint();
        LocalDateTime upperEndpoint = valueRange.upperEndpoint();

        // 逻辑表名
        String logicTableName = rangeShardingValue.getLogicTableName();
        List<String> tables = new ArrayList<>();


        if (Duration.between(lowerEndpoint, upperEndpoint).toDays() > 365) {
            throw new RuntimeException("不能查询大于一年的数据");
        }


        while (lowerEndpoint.compareTo(upperEndpoint) <= 0) {
            // 添加到集合
            tables.add(buildTable(logicTableName, lowerEndpoint));
            // 往后加一个月
            lowerEndpoint = lowerEndpoint.plusMonths(1);
        }

        return tables;
    }

    private String buildTable(String logicTableName, LocalDateTime startTime) {
        String timeStr = DateUtil.formatLocalDateTime(startTime);
        String year = timeStr.substring(2, 4);
        String month = timeStr.substring(5, 7);

        return logicTableName + "_" + year + month;
    }
}

开始测试

@SpringBootTest
public class ShardingTest {



    @Resource
    private TraceMapper traceMapper;


    @Test
    public void testInsertTrace() {
        TraceDO traceDO = new TraceDO();
        traceDO.setTraceInfo("traceInfo");
        traceDO.setTraceTime(LocalDateTime.of(2024,04,19,00,01,02));
        traceMapper.insert(traceDO);
    }

    @Test
    public void testSelectTrace() {
        LocalDateTime start = LocalDateTime.of(2024,4,1,0,0,0);
        LocalDateTime end = LocalDateTime.of(2024,5,19,0,1,2);


        List<TraceDO> traceDOS = traceMapper.selectList(new LambdaQueryWrapper<TraceDO>().between(TraceDO::getTraceTime,start, end).orderByDesc(TraceDO::getTraceTime).last("limit 1"));
        traceDOS.forEach(System.out::println);
    }

}

执行插入方法

2024-05-07 15:49:03.530  INFO 15316 --- [           main] com.alibaba.druid.pool.DruidDataSource   : {dataSource-1} inited
2024-05-07 15:49:03.675  INFO 15316 --- [           main] o.a.s.core.log.ConfigurationLogger       : ShardingRuleConfiguration:
tables:
  trace:
    actualDataNodes: db0.trace_$->{2401..2912}
    keyGenerator:
      column: id
      type: SNOWFLAKE
    logicTable: trace
    tableStrategy:
      standard:
        preciseAlgorithmClassName: com.tom.configuration.TraceShardingAlgorithm
        rangeAlgorithmClassName: com.tom.configuration.TraceRangeShardingAlgorithm
        shardingColumn: trace_time

2024-05-07 15:49:03.677  INFO 15316 --- [           main] o.a.s.core.log.ConfigurationLogger       : Properties:
sql.show: 'true'

2024-05-07 15:49:03.682  INFO 15316 --- [           main] ShardingSphere-metadata                  : Loading 1 logic tables' meta data.
2024-05-07 15:49:03.700  INFO 15316 --- [           main] ShardingSphere-metadata                  : Loading 9 tables' meta data.
2024-05-07 15:49:03.763  INFO 15316 --- [           main] ShardingSphere-metadata                  : Meta data load finished, cost 85 milliseconds.
 _ _   |_  _ _|_. ___ _ |    _ 
| | |\/|_)(_| | |_\  |_)||_|_\ 
     /               |         
                        3.5.3.2 
2024-05-07 15:49:04.252  INFO 15316 --- [           main] com.tom.test.ShardingTest                : Started ShardingTest in 2.855 seconds (JVM running for 3.531)
2024-05-07 15:49:04.850  INFO 15316 --- [           main] ShardingSphere-SQL                       : Logic SQL: INSERT INTO trace  ( id, trace_info, trace_time )  VALUES  ( ?, ?, ? )
2024-05-07 15:49:04.850  INFO 15316 --- [           main] ShardingSphere-SQL                       : SQLStatement: InsertStatementContext(super=CommonSQLStatementContext(sqlStatement=org.apache.shardingsphere.sql.parser.sql.statement.dml.InsertStatement@15cee630, tablesContext=org.apache.shardingsphere.sql.parser.binder.segment.table.TablesContext@2e40fdbd), tablesContext=org.apache.shardingsphere.sql.parser.binder.segment.table.TablesContext@2e40fdbd, columnNames=[id, trace_info, trace_time], insertValueContexts=[InsertValueContext(parametersCount=3, valueExpressions=[ParameterMarkerExpressionSegment(startIndex=61, stopIndex=61, parameterMarkerIndex=0), ParameterMarkerExpressionSegment(startIndex=64, stopIndex=64, parameterMarkerIndex=1), ParameterMarkerExpressionSegment(startIndex=67, stopIndex=67, parameterMarkerIndex=2)], parameters=[1787751489014648833, traceInfo, 2024-04-19T00:01:02])], generatedKeyContext=Optional.empty)
2024-05-07 15:49:04.850  INFO 15316 --- [           main] ShardingSphere-SQL                       : Actual SQL: db0 ::: INSERT INTO trace_2404  ( id, trace_info, trace_time )  VALUES  (?, ?, ?) ::: [1787751489014648833, traceInfo, 2024-04-19T00:01:02]
2024-05-07 15:49:04.889  INFO 15316 --- [ionShutdownHook] com.alibaba.druid.pool.DruidDataSource   : {dataSource-1} closing ...
2024-05-07 15:49:04.984  INFO 15316 --- [ionShutdownHook] com.alibaba.druid.pool.DruidDataSource   : {dataSource-1} closed

执行查询方法

2024-05-07 15:50:05.585  INFO 4632 --- [           main] o.a.s.core.log.ConfigurationLogger       : ShardingRuleConfiguration:
tables:
  trace:
    actualDataNodes: db0.trace_$->{2401..2912}
    keyGenerator:
      column: id
      type: SNOWFLAKE
    logicTable: trace
    tableStrategy:
      standard:
        preciseAlgorithmClassName: com.tom.configuration.TraceShardingAlgorithm
        rangeAlgorithmClassName: com.tom.configuration.TraceRangeShardingAlgorithm
        shardingColumn: trace_time

2024-05-07 15:50:05.587  INFO 4632 --- [           main] o.a.s.core.log.ConfigurationLogger       : Properties:
sql.show: 'true'

2024-05-07 15:50:05.591  INFO 4632 --- [           main] ShardingSphere-metadata                  : Loading 1 logic tables' meta data.
2024-05-07 15:50:05.610  INFO 4632 --- [           main] ShardingSphere-metadata                  : Loading 9 tables' meta data.
2024-05-07 15:50:05.679  INFO 4632 --- [           main] ShardingSphere-metadata                  : Meta data load finished, cost 92 milliseconds.
 _ _   |_  _ _|_. ___ _ |    _ 
| | |\/|_)(_| | |_\  |_)||_|_\ 
     /               |         
                        3.5.3.2 
2024-05-07 15:50:06.207  INFO 4632 --- [           main] com.tom.test.ShardingTest                : Started ShardingTest in 2.971 seconds (JVM running for 3.65)
2024-05-07 15:50:06.973  INFO 4632 --- [           main] ShardingSphere-SQL                       : Logic SQL: SELECT  id,trace_info,trace_time,deleted,version  FROM trace  WHERE deleted=false     AND (trace_time BETWEEN ? AND ?) ORDER BY trace_time DESC limit 1
2024-05-07 15:50:06.973  INFO 4632 --- [           main] ShardingSphere-SQL                       : SQLStatement: SelectStatementContext(super=CommonSQLStatementContext(sqlStatement=org.apache.shardingsphere.sql.parser.sql.statement.dml.SelectStatement@283bb8b7, tablesContext=org.apache.shardingsphere.sql.parser.binder.segment.table.TablesContext@25e95af1), tablesContext=org.apache.shardingsphere.sql.parser.binder.segment.table.TablesContext@25e95af1, projectionsContext=ProjectionsContext(startIndex=8, stopIndex=47, distinctRow=false, projections=[ColumnProjection(owner=null, name=id, alias=Optional.empty), ColumnProjection(owner=null, name=trace_info, alias=Optional.empty), ColumnProjection(owner=null, name=trace_time, alias=Optional.empty), ColumnProjection(owner=null, name=deleted, alias=Optional.empty), ColumnProjection(owner=null, name=version, alias=Optional.empty)]), groupByContext=org.apache.shardingsphere.sql.parser.binder.segment.select.groupby.GroupByContext@4fa8297b, orderByContext=org.apache.shardingsphere.sql.parser.binder.segment.select.orderby.OrderByContext@6644bdf5, paginationContext=org.apache.shardingsphere.sql.parser.binder.segment.select.pagination.PaginationContext@13cf5f8a, containsSubquery=false)
2024-05-07 15:50:06.973  INFO 4632 --- [           main] ShardingSphere-SQL                       : Actual SQL: db0 ::: SELECT  id,trace_info,trace_time,deleted,version  FROM trace_2404  WHERE deleted=false     AND (trace_time BETWEEN ? AND ?) ORDER BY trace_time DESC limit 1 ::: [2024-04-01T00:00, 2024-05-19T00:01:02]
2024-05-07 15:50:06.973  INFO 4632 --- [           main] ShardingSphere-SQL                       : Actual SQL: db0 ::: SELECT  id,trace_info,trace_time,deleted,version  FROM trace_2405  WHERE deleted=false     AND (trace_time BETWEEN ? AND ?) ORDER BY trace_time DESC limit 1 ::: [2024-04-01T00:00, 2024-05-19T00:01:02]
TraceDO(id=1785190384815861761, traceInfo=traceInfo, traceTime=2024-05-19T00:01:02)
2024-05-07 15:50:07.135  INFO 4632 --- [ionShutdownHook] com.alibaba.druid.pool.DruidDataSource   : {dataSource-1} closing ...
2024-05-07 15:50:07.140  INFO 4632 --- [ionShutdownHook] com.alibaba.druid.pool.DruidDataSource   : {dataSource-1} closed

Process finished with exit code 0

<think>首先,用户的问题是关于使用ShardingSphere-Proxy实现分表功能,特别是分表配置和使用教程。用户引用了几个来源,我需要参考这些引用来提供准确的信息。回顾用户提供的引用:-引用[^1]:提到启动ShardingSphere-Proxy并连接到它。-引用[^2]:给出启动命令(在Linux上)。-引用[^3]:讨论联邦查询和跨库关联查询。-引用[^4]:显示插入数据的示例。用户的核心问题是“ShardingSphere-Proxy分表配置与使用教程”,所以我需要专注于分表功能的配置。关键点:-ShardingSphere-Proxy是一个数据库中间件,用于分库分表。-分表功能涉及将一个大表拆分成多个小表,基于某些策略(如按ID取模、按范围等)。根据引用和我的知识:-配置通常通过YAML文件进行。-需要定义数据源、分片规则等。步骤结构:1.**准备环境**:安装ShardingSphere-Proxy。2.**配置分表规则**:在配置文件中定义分表策略。3.**启动Proxy**:运行Proxy服务。4.**使用Proxy**:通过客户端(如MySQL客户端)连接到Proxy并执行SQL。5.**示例操作**:创建表、插入数据、查询数据。从引用中提取相关信息:-引用[^1]和[^2]:启动Proxy的命令。-引用[^4]:插入数据的SQL示例。-引用[^3]:联邦查询,但用户问题主要是分表,所以可能次要。用户上一次问题可能是关于分表,但在这个对话中,用户直接问了这个。系统指令要求生成相关问题,所以最后要添加相关问题。回答结构:-用中文回答。-结构清晰:分步解释。-使用$...$和$$...$$格式的数学表达式(如果需要),但这里可能主要是配置和代码,不是数学。-末尾添加引用标识。-生成相关问题。可能的数学:如果有分片算法,如取模,可以用数学表达式表示,例如分片键mod分片数。配置示例:-分表规则可能涉及行表达式或标准分片算法。-例如,按user_id分表到多个表。从引用[^3],链接到文档:https://shardingsphere.apache.org/document/5.4.1/cn/user-manual/shardingsphere-proxy/yaml-config/rules/,这应该包含配置细节。步骤大纲:1.安装和启动ShardingSphere-Proxy。-引用[^2]:启动命令`./start.sh`或`start.bat`。2.配置分表规则。-编辑`config-sharding.yaml`文件。-定义数据源、分片规则。3.示例:创建一个分表配置。-假设表`t_order`按`order_id`分表。4.连接到Proxy并执行SQL。-引用[^1]:使用Navicat或MySQL客户端。-引用[^4]:插入数据示例。5.验证分表效果。生成相关问题:-基于内容,如优化、性能、错误处理等。最终回答结构:-引言:简要介绍。-步骤1:环境准备。-步骤2:配置分表规则。-步骤3:启动Proxy。-步骤4:使用示例。-相关问题。</think>### ShardingSphere-Proxy 分表配置与使用教程 ShardingSphere-Proxy 是一个开源的数据库中间件,支持分表、分库等分布式功能。它通过代理模式拦截 SQL 请求,并根据配置的分片规则将数据分散存储到多个物理表中,从而提升性能和可扩展性。下面我将以分表功能为核心,分步解释配置和使用流程。所有步骤基于 ShardingSphere-Proxy 5.x 版本(如 v5.4.1 或 v5.5.0),参考官方文档和用户引用内容。 --- ### 步骤 1: 环境准备与安装 首先,确保已安装 ShardingSphere-Proxy 和依赖环境(如 Java 8+ 和 MySQL)。 - **下载与安装**: 从 [Apache ShardingSphere 官网](https://shardingsphere.apache.org/) 下载最新版本(如 `apache-shardingsphere-5.5.0-shardingsphere-proxy-bin.tar.gz`),解压到本地目录。 - **配置数据源**: 编辑 `conf/config-sharding.yaml` 文件,定义后端数据库连接。例如,配置一个 MySQL 数据源: ```yaml dataSources: ds_0: url: jdbc:mysql://localhost:3306/db0?useSSL=false username: root password: root ds_1: url: jdbc:mysql://localhost:3306/db1?useSSL=false username: root password: root ``` 这里假设有两个物理数据库 `db0` 和 `db1`,用于存储分表后的数据[^2]。 --- ### 步骤 2: 配置分表规则 分表规则在 `conf/config-sharding.yaml` 文件中定义,核心是分片算法和绑定表。以下以订单表 `t_order` 为例,按 `order_id` 取模分表(分成 2 个物理表)。 - **分表规则配置**: ```yaml rules: - !SHARDING tables: t_order: # 逻辑表名 actualDataNodes: ds_${0..1}.t_order_${0..1} # 物理表位置:ds0.t_order_0, ds0.t_order_1, ds1.t_order_0, ds1.t_order_1 tableStrategy: standard: shardingColumn: order_id # 分片键 shardingAlgorithmName: t_order_table_mod # 分表算法名称 shardingAlgorithms: t_order_table_mod: type: MOD # 取模算法 props: sharding-count: 2 # 分表数量 bindingTables: - t_order # 绑定表,确保关联查询效率 ``` **关键说明**: - `actualDataNodes`:定义物理表位置,格式为 `数据源名.表名_分片后缀`。 - 分表算法 `MOD`:基于分片键 `order_id` 计算分表位置,公式为 $ \text{分表索引} = \text{order_id} \mod 2 $。例如,`order_id=3` 的数据会路由到 `t_order_1`(因为 $3 \mod 2 = 1$)。 - `bindingTables`:避免跨表关联查询时的笛卡尔积问题[^3]。 - **其他分表算法**: 支持范围分片(如按时间)、哈希分片等。例如,按月分表算法: ```yaml shardingAlgorithms: monthly_table: type: INTERVAL # 时间范围算法 props: datetime-pattern: "yyyy-MM" # 时间格式 datetime-lower: "2024-01" # 起始时间 datetime-upper: "2024-12" # 结束时间 sharding-suffix-pattern: "yyyyMM" # 表后缀格式 ``` --- ### 步骤 3: 启动 ShardingSphere-Proxy 配置成后,启动 Proxy 服务: - **启动命令**: - Windows:进入 `bin` 目录,双击 `start.bat`[^1]。 - Linux:运行 `./start.sh`[^2]。 启动成功后,日志显示监听端口(默认 3307),表示 Proxy 已就绪。 --- ### 步骤 4: 使用 Proxy 执行分表操作 通过 MySQL 客户端(如 Navicat 或命令行)连接到 Proxy,并执行 SQL。Proxy 会将逻辑 SQL 路由到正确的物理表。 - **连接 Proxy**: - 地址:`localhost:3307` - 用户名/密码:在 `conf/server.yaml` 中定义(默认 `root/root`)[^1]。 - **创建逻辑表**: 在客户端执行 DDL,创建逻辑表(Proxy 自动映射到物理表): ```sql CREATE TABLE t_order ( order_id BIGINT PRIMARY KEY, user_id INT, amount DECIMAL(10,2) ); ``` 此操作会在后端数据库生成物理表(如 `db0.t_order_0` 和 `db1.t_order_1`)。 - **插入数据**: 插入数据时,Proxy 根据分片键 `order_id` 自动路由: ```sql INSERT INTO t_order (order_id, user_id, amount) VALUES (1, 1, 10.0), -- 路由到 t_order_1(因为 1 mod 2 = 1) (2, 2, 20.0); -- 路由到 t_order_0(因为 2 mod 2 = 0) ``` 数据分散存储,提升写入性能[^4]。 - **查询数据**: 执行查询时,Proxy 聚合所有分表结果: ```sql SELECT * FROM t_order WHERE user_id = 1; -- 自动扫描所有物理表 ``` 对于跨表关联查询,可启用联邦查询功能[^3]。 --- ### 常见问题与验证 - **验证分表效果**: 直接连接到后端数据库(如 MySQL),检查 `db0.t_order_0` 和 `db1.t_order_1` 中的数据分布是否符合分片规则。 - **性能注意事项**: - 分片键选择:高频查询字段(如 `user_id`)作为分片键可减少跨表扫描。 - 分表数量:建议 $2^n$ 个分片(如 2、4、8),以优化取模计算效率。 - **错误处理**: 如果 SQL 未指定分片键(如 `INSERT INTO t_order (user_id, amount) VALUES (3, 30.0)`),Proxy 可能报错或使用默认路由。需在配置中启用 `allow-hint` 或指定默认算法[^3]。 > 引用说明:以上步骤整合了 ShardingSphere-Proxy 的启动、连接和分表操作[^1][^2][^3][^4]。详细配置可参考 [官方文档](https://shardingsphere.apache.org/document/current/cn/user-manual/shardingsphere-proxy/yaml-config/rules/)。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值