shardingsphere-jdbc分库分表

1.shardingsphere介绍

Apache ShardingSphere 是一款分布式 SQL 事务和查询引擎,可通过数据分片、弹性伸缩、加密等能力对任意数据库进行增强。

Apache ShardingSphere 是一款分布式的数据库生态系统, 可以将任意数据库转换为分布式数据库,并通过数据分片、弹性伸缩、加密等能力对原有数据库进行增强。

Apache ShardingSphere 设计哲学为 Database Plus,旨在构建异构数据库上层的标准和生态。 它关注如何充分合理地利用数据库的计算和存储能力,而并非实现一个全新的数据库。 它站在数据库的上层视角,关注它们之间的协作多于数据库自身。

具体介绍参见官网

2.理论知识

2.1.分片策略

分片策略是分片键分片算法的组合策略,真正用于实现数据分片操作的是分片键与相应的分片算法。在分片策略中,分片键确定了数据的拆分依据,分片算法则决定了如何对分片键值运算,将数据路由到哪个物理分片中。

由于分片算法的独立性,使得分片策略具有更大的灵活性和可扩展性。这意味着可以根据具体需求选择不同的分片算法,或者开发自定义的分片算法,以适应各种不同的分片场景。在分表和分库时使用分片策略和分片算法的方式是一致的

注意:如果在某种分片策略中使用了不受支持的SQL操作符,比如 MYSQL 某些函数等,那么系统将无视分片策略,进行全库表路由操作。这个在使用时要慎重!

ShardingSphere对外提供了standardcomplexhintinlinenone5种分片策略。不同的分片策略可以搭配使用不同的分片算法,这样可以灵活的应对复杂业务场景。

下面介绍几种常用的分片策略及其配置。

2.1.1.标准分片策略

标准分片策略(standard)适用于具有单一分片键的标准分片场景。该策略支持精确分片,即在SQL中包含=in操作符,以及范围分片,包括BETWEEN AND><>=<=等范围操作符。

该策略下有两个属性,分片字段shardingColumn和分片算法名shardingAlgorithmName

spring:
  shardingsphere:
    rules:
      sharding:
        tables:
          t_order: # 逻辑表名称
            # 数据节点:数据库.分片表
            actual-data-nodes: db$->{0..1}.t_order_${1..10}
            # 分库策略
            databaseStrategy: # 分库策略
              standard: # 用于单分片键的标准分片场景
                shardingColumn: order_id # 分片列名称
                shardingAlgorithmName: # 分片算法名称
           tableStrategy: # 分表策略,同分库策略
2.1.2.行表达式分片策略

行表达式分片策略(inline)适用于具有单一分片键的简单分片场景,支持SQL语句中=in操作符。

它的配置相当简洁,该分片策略支持在配置属性algorithm-expression中书写Groovy表达式,用来定义对分片健的运算逻辑,无需单独定义分片算法了。

spring:
  shardingsphere:
    rules:
      sharding:
        tables:
          t_order: # 逻辑表名称
            # 数据节点:数据库.分片表
            actual-data-nodes: db$->{0..1}.t_order_${1..10}
            # 分库策略
            databaseStrategy: # 分库策略
              inline:   # 行表达式类型分片策略
                algorithm-expression: db$->{order_id % 2} Groovy表达式
            tableStrategy: # 分表策略,同分库策略
2.1.3.复合分片策略

复合分片策略(complex)适用于多个分片键的复杂分片场景,属性shardingColumns中多个分片健以逗号分隔。支持 SQL 语句中有>>=<=<=INBETWEEN AND 等操作符。

比如:我们希望通过user_idorder_id等多个字段共同运算得出数据路由到具体哪个分片中,就可以应用该策略。

spring:
  shardingsphere:
    rules:
      sharding:
        tables:
          t_order: # 逻辑表名称
            # 数据节点:数据库.分片表
            actual-data-nodes: db$->{0..1}.t_order_${1..10}
            # 分库策略
            databaseStrategy: # 分库策略
              complex: # 用于多分片键的复合分片场景
                shardingColumns: order_id,user_id # 分片列名称,多个列以逗号分隔
                shardingAlgorithmName: # 分片算法名称
            tableStrategy: # 分表策略,同分库策略

2.2.分片算法

ShardingSphere 内置了多种分片算法,按照类型可以划分为自动分片算法标准分片算法复合分片算法Hint 分片算法,能够满足我们绝大多数业务场景的需求。

下面介绍几种常用的分片算法及其配置。

2.2.1.自动分片算法
1.MOD

取模分片算法是内置的一种比较简单的算法,定义算法时类型MOD,表达式大致(分片健/数据库实例) % sharding-count,它只有一个 props 属性sharding-count代表分片表的数量。

这个 sharding-count 数量使用时有点小坑,比如db0db1都有分片表t_order_1,那么实际上数量只能算一个。YML核心配置如下:

spring:
  shardingsphere:
    rules:
      sharding:
        # 自动分片表规则配置
        auto-tables:
          t_order:
            actual-data-sources: db$->{0..1}
            sharding-strategy:
              standard:
                sharding-column: order_date
                sharding-algorithm-name: t_order_table_mod
        # 分片算法定义
        sharding-algorithms:
          t_order_table_mod:
            type: MOD # 取模分片算法
            props:
              # 指定分片数量
              sharding-count: 6
        tables:
          t_order: # 逻辑表名称
            actual-data-nodes: db$->{0..1}.t_order_${0..2}
            # 分库策略
            database-strategy:
            ....
            # 分表策略
            table-strategy:
              standard:
                sharding-column: order_id
                sharding-algorithm-name: t_order_table_mod
2.HASH_MOD

哈希取模分片算法是内置取模分片算法的一个升级版本,定义算法时类型HASH_MOD,也只有一个props属性sharding-count代表分片的数量。表达式hash(分片健/数据库实例) % sharding-count

YML核心配置如下:

spring:
  shardingsphere:
    rules:
      sharding:
        # 自动分片表规则配置
        auto-tables:
          t_order:
            actual-data-sources: db$->{0..1}
            sharding-strategy:
              standard:
                sharding-column: order_date
                sharding-algorithm-name: t_order_table_hash_mod
        # 分片算法定义
        sharding-algorithms:
          t_order_table_hash_mod:
            type: HASH_MOD # 哈希取模分片算法
            props:
              # 指定分片数量
              sharding-count: 6
        tables:
          t_order: # 逻辑表名称
            actual-data-nodes: db$->{0..1}.t_order_${0..2}
            # 分库策略
            database-strategy:
            ....
            # 分表策略
            table-strategy:
              standard:
                sharding-column: order_id
                sharding-algorithm-name: t_order_table_hash_mod
2.2.2.标准分片算法
1.INLINE

行表达式分片算法,适用于比较简单的分片场景,利用Groovy表达式在算法属性内,直接书写分片逻辑,省却了配置和代码开发,只支持SQL语句中的 = 和 IN 的分片操作,只支持单分片键

该算法有两属性:

  • algorithm-expression:编写Groovy的表达式,比如: t_order_$->{t_order_id % 3} 表示根据分片健 t_order_id 取模获得 3 张 t_order 分片表 t_order_0 到 t_order_2。
  • allow-range-query-with-inline-sharding:由于该算法只支持含有 = 和 IN 操作符的SQL,一旦SQL使用了范围查询 >、< 等操作会报错。要想执行范围查询成功,该属性开启为true即可,一旦开启范围查询会无视分片策略,进行全库表路由查询,这个要慎重开启

YML核心配置如下:

spring:
  shardingsphere:
    # 具体规则配置
    rules:
      sharding:
        # 分片算法定义
        sharding-algorithms:
          # 标准分片算法
          # 行表达式分片算法
          t_order_table_inline:
            type: INLINE
            props:
              algorithm-expression:	t_order_$->{order_id % 3} # 分片算法的行表达式
              allow-range-query-with-inline-sharding: false # 是否允许范围查询。注意:范围查询会无视分片策略,进行全路由,默认 false
        tables:
          # 逻辑表名称
          t_order:
            # 数据节点:数据库.分片表
            actual-data-nodes: db$->{0..1}.t_order_${0..2}
            # 分库策略
            database-strategy:
              standard:
                sharding-column: order_id
                sharding-algorithm-name: t_order_database_algorithms
            # 分表策略
            table-strategy:
              standard:
                sharding-column: order_id
                sharding-algorithm-name: t_order_table_inline
2.INTERVAL

时间范围分片算法,针对于时间字段(字符串类型)作为分片健的范围分片算法,适用于按照天、月、年这种固定区间的数据分片。
上边使用其它时间分片算法时,用的都是t_order_n后缀编号格式的分片表。但业务上往往需要的可能是按月、年t_order_yyyyMM的这种分片表格式。

时间范围分片算法(INTERVAL),可以轻松实现这种场景,它的属性比较多,逐个解释下:

  • datetime-pattern:分片健值的时间格式,必须是Java DateTimeFormatter类支持的转换类型
  • datetime-lower:分片健值的下界,超过会报错,格式必须与datetime-pattern一致
  • datetime-upper:分片健值的上界,超过会报错,格式必须与datetime-pattern一致
  • sharding-suffix-pattern:分片表后缀名格式,yyyyMM、yyyyMMdd等格式,分片表格式的定义要结合datetime-interval-unit的单位,比如:t_order_yyyyMM格式表示分片表存的月的数据,t_order_yyyy格式表示分片表存的年的数据;
  • datetime-interval-unit:分片间隔单位,超过该时间间隔将进入下一分片。它遵循 Java ChronoUnit 枚举,比如:MONTHSDAYS等;
  • datetime-interval-amount:分片间隔数,和datetime-interval-unit是紧密配合使用;

接下来实现个按月存储数据的场景,用t_order_202401t_order_202406 6张分片表存储前半年的数据,每张分片表存储一个月的数据。interval_value字段作为分片健,时间字符串类型,允许的分片值时间范围 2024-01-01 00:00:00~2024-06-30 23:59:59 不在范围内插入报错。

spring:
  shardingsphere:
    rules:
      sharding:
        # 分片算法定义
        sharding-algorithms:
          t_order_database_mod:
            type: MOD
            props:
              sharding-count: 2 # 指定分片数量
          t_order_table_interval:
            type: INTERVAL
            props:
              datetime-pattern: "yyyy-MM-dd HH:mm:ss"  # 分片字段格式
              datetime-lower: "2024-01-01 00:00:00"  # 范围下限
              datetime-upper: "2024-06-30 23:59:59"  # 范围上限
              sharding-suffix-pattern: "yyyyMM"  # 分片名后缀,可以是MM,yyyyMMdd等。
              datetime-interval-amount: 1  # 分片间隔,这里指一个月
              datetime-interval-unit: "MONTHS" # 分片间隔单位
        tables:
          # 逻辑表名称
          t_order:
            # 数据节点:数据库.分片表
            actual-data-nodes: db$->{0..1}.t_order_${202401..202406}
            # 分库策略
            database-strategy:
              standard:
                sharding-column: order_id
                sharding-algorithm-name: t_order_database_mod
            # 分表策略
            table-strategy:
              standard:
                sharding-column: interval_value
                sharding-algorithm-name: t_order_table_interval
            keyGenerateStrategy:
              column: id
              keyGeneratorName: t_order_snowflake
2.2.3.复合分片算法
1.COMPLEX_INLINE

复合行表达式分片算法,适用于多分片健的简单分片场景,和行表达式分片算法使用的方式基本一样。多了一个属性sharding-columns分片列名称,多个列用逗号分隔。特别注意:使用多分片键复合算法,一定要基于复合分片策略进行设置

我们对现有的分库分表算法进行了改进,将分片策略修改为complexsharding-columns单个分片键升级为多个分片键逗号分隔。例如,将分库表达式从db$->{order_id % 2}调整为db$->{(order_id + user_id) % 2},就实现了多个分片键的应用。

yml核心的配置如下:

spring:
  shardingsphere:
    # 具体规则配置
    rules:
      sharding:
        # 分片算法定义
        sharding-algorithms:
          t_order_database_complex_inline_algorithms:
            type: COMPLEX_INLINE
            props:
              sharding-columns: order_id, user_id # 分片列名称,多个列用逗号分隔。
              algorithm-expression: db$->{(order_id + user_id) % 2} # 分片算法的行表达式
              allow-range-query-with-inline-sharding: false # 是否允许范围查询。注意:范围查询会无视分片策略,进行全路由,默认 false
          # 11、复合行表达式分片算法
          t_order_table_complex_inline:
            type: COMPLEX_INLINE
            props:
              sharding-columns: order_id, user_id # 分片列名称,多个列用逗号分隔。
              algorithm-expression: t_order_$->{ (order_id + user_id) % 3 } # 分片算法的行表达式
              allow-range-query-with-inline-sharding: false # 是否允许范围查询。注意:范围查询会无视分片策略,进行全路由,默认 false
        tables:
          # 逻辑表名称
          t_order:
            # 数据节点:数据库.分片表
            actual-data-nodes: db$->{0..1}.t_order_${0..2}
            # 分库策略
            database-strategy:
              complex:
                shardingColumns: order_id, user_id
                sharding-algorithm-name: t_order_database_complex_inline_algorithms
            # 分表策略
            table-strategy:
              complex:
                shardingColumns: order_id, user_id
                sharding-algorithm-name: t_order_table_complex_inline
            keyGenerateStrategy:
              column: id
              keyGeneratorName: t_order_snowflake
2.CLASS_BASED

CLASS_BASED分片算法可以让使用者通过自定义ComplexKeysShardingAlgorithm的实现类来实现复杂的分库分表策略,自定义分库算法需要实现org.apache.shardingsphere.sharding.api.sharding.complex.ComplexKeysShardingAlgorithm接口,自定义分表算法需要实现org.apache.shardingsphere.sharding.api.sharding.complex.ComplexKeysShardingAlgorithm接口,配置样例如下

spring:
  shardingsphere:
    # 具体规则配置
    rules:
      sharding:
        tables:
          con_file_upload:
            actualDataNodes: ds${1..2}.con_file_upload_${1..3}  # 配置数据表分片规则
            databaseStrategy: # 数据库分片策略
              # 有三种 standard,complex hint
              complex:
                # todo 这里要是standard,则为shardingColumn
                shardingColumns: id   # 使用 user_id 作为分片键
                shardingAlgorithmName: database_inline # 这是一个算法名称,在下面shardingAlgorithms 下定义的
            tableStrategy:
              complex:
                shardingColumns: id  
                shardingAlgorithmName: con_file_upload_inline  # 使用自定义的分片算法
        shardingAlgorithms:
          database_inline: # 自定义的算法名称,上边有用到
            type: CLASS_BASED
            props:
              # 分片策略类型,支持 STANDARD、COMPLEX 或 HINT(不区分大小写)
              strategy: COMPLEX
              # 分片算法全限定名
              algorithmClassName: org.apache.shardingsphere.custom.algorithm.TianYiDatabaseComplexKeysShardingAlgorithm
          con_file_upload_inline:
            type: CLASS_BASED
            props:
              # 分片策略类型,支持 STANDARD、COMPLEX 或 HINT(不区分大小写)
              strategy: COMPLEX
              # 分片算法全限定名
              algorithmClassName: org.apache.shardingsphere.custom.algorithm.TianYiTableComplexKeysShardingAlgorithm  

这里分库分表都使用了自定义算法,算法分别在

org.apache.shardingsphere.custom.algorithm.TianYiDatabaseComplexKeysShardingAlgorithm

org.apache.shardingsphere.custom.algorithm.TianYiDatabaseComplexKeysShardingAlgorithm

具体可看两个类的具体实现。

2.3.基因法

基因法

基因法原理 : 对一个数取余2的n次方,那么余数就是这个数的二进制的最后n位数。

举例
十进制数对10的n次幂取余,余数是10进制数的最后n位, 比如

11 % 10,余数 1

122 % 10,余数 2

122 % 100 , 余数 22

同理,对一个数取余2的n次方,余数就是这个数的二进制的最后n位数,然后可以再转为10进制。

为什么分片数要是2的n次幂

  • 可以将取模算法优化成性能更高的位运算算法。
如: 11 % 4 等于 11 & (4-1)
  • 可以将表在多个库中均匀分布。
通常分表会和分库一起进行,比如需要分成2个库8个表,分表和分库的数量都是2的n次幂,可以实现均匀分布,8个表均分到2个库中,每个库4个表。
  • 第三个也是最重要的原因,可以减少扩容时迁移的数据量,只需要迁移一半。
比如 原来分2个表,order_0,order_1

userId % 2 = 0 ,对应 order_0
userId % 2 = 1 , 对应 order_1
此时扩容到4个表

userId % 4 = 0 ,对应 order_0
userId % 4 = 1 , 对应 order_1
userId % 4 = 2 ,对应 order_2
userId % 4 = 3 , 对应 order_3
只需要迁移原来在 order_0, order_1 中,且 userId % 4 >=2 数据就行。

userId % 4 = 2的数据, 从 order_0 迁移到 order_2
userId % 4 = 3的数据, 从order_1 迁移到 order_3

根据以上理论知识,分库分表要保证库和表的数量都为2的N次方,这样方便以后扩容时做数据迁移。

3.分库分表

本节针对不同的数据库集成shardingsphere-jdbc,会介绍常用的配置以及注意事项。

3.1.环境说明

3.1.1.版本说明

项目中应用到的相关组件列举如下

条目 版本
springboot 3.2.0
mybatis-plus-spring-boot3-starter 3.5.4.1
shardingsphere-jdbc 5.5.2
mysql server 8.0.30
mysql驱动 8.3.0
kingbase kingbase_v009r001c002b0014_single_x86
kingbase8驱动 8.6.0
3.1.2.通用配置

项目中采用mybatis-plus框架,mybatis-plus的配置是固定的,mapper层在不同数据库下也是通用的,shardingsphere-jdbc采用数据库驱动代理的方式实现分库分表数据的访问,各类型数据库的配置主要区别在数据库驱动以及连接url上,并且shardingsphere-jdbc的主配置文件也是固定的。

mybatis-plus配置

mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!-- 全局参数 -->
    <settings>
        <!-- 使全局的映射器启用或禁用缓存 -->
        <setting name="cacheEnabled" value="true"/>
        <!-- 允许JDBC 支持自动生成主键 -->
        <setting name="useGeneratedKeys" value="true"/>
        <!-- 配置默认的执行器.SIMPLE就是普通执行器;REUSE执行器会重用预处理语句(prepared statements);BATCH执行器将重用语句并执行批量更新 -->
        <setting name="defaultExecutorType" value="SIMPLE"/>
        <!-- 指定 MyBatis 所用日志的具体实现 -->
        <setting name="logImpl" value="org.apache.ibatis.logging.stdout.StdOutImpl"/>
    </settings>

</configuration>

application.yml

# mybatis-plus 配置
mybatis-plus:
    # 搜索指定包别名
    # type-aliases-package: com.tianyi.framework.**.domain,com.tianyi.framework.**.model
    # 配置mapper的扫描,找到所有的mapper.xml映射文件
    mapper-locations: classpath*:com/tianyi/**/mapper/*Mapper.xml
    # 加载全局的配置文件
    config-location: classpath:mybatis/mybatis-config.xml
    global-config:
        db-config:
            id-type: assign_id
            # 逻辑已删除值(默认为 1)
            logic-delete-value: 1
            # 逻辑未删除值(默认为 0)
            logic-not-delete-value: 0
        # 关闭logo
        banner: true
shardingsphere-jdbc配置

主配置

spring:
    # 数据源配置
    datasource:
        driver-class-name: org.apache.shardingsphere.driver.ShardingSphereDriver
        url: jdbc:shardingsphere:classpath:sharding.yml #固定写法,必须按照这个格式写!
        druid:
            # 初始连接数
            initial-size: 5
            # 最小连接池数量
            min-idle: 10
            # 最大连接池数量
            maxActive: 20
            # 配置获取连接等待超时的时间
            maxWait: 60000
            #配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
            timeBetweenEvictionRunsMillis: 60000
            # 配置一个连接在池中最小生存的时间,单位是毫秒
            minEvictableIdleTimeMillis: 300000
            # 配置一个连接在池中最大生存的时间,单位是毫秒
            maxEvictableIdleTimeMillis: 900000
            # 配置检测连接是否有效
            # validationQuery: SELECT 1 FROM DUAL
            testWhileIdle: true
            testOnBorrow: false
            testOnReturn: false
            # 监控相关的全局配置
			...

sharding.yml

# ShardingSphere 配置模式,配置为 Standalone(独立模式)
mode:
  type: Standalone
  repository:
    type: JDBC # 使用 JDBC 作为注册中心,支持通过数据库持久化配置

props:
  sql-show: true # 打印具体sql,便于调试
  # sql-simple: true

dataSources:
  ds1:
    dataSourceClassName: com.alibaba.druid.pool.DruidDataSource
    driverClassName: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://192.168.245.128:3306/test?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&allowMultiQueries=true&nullCatalogMeansCurrent=true
    username: xxx
    password: xxx
  ds2:
    dataSourceClassName: com.alibaba.druid.pool.DruidDataSource
    driverClassName: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://192.168.245.128:3306/test1?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&allowMultiQueries=true&nullCatalogMeansCurrent=true
    username: xxx
    password: xxx
rules:
  - !SINGLE
    tables:
      - "ds*.*"
  - !SHARDING
    tables:
      con_file_upload:
        actualDataNodes: ds${1..2}.con_file_upload_${1..3}  # 配置数据表分片规则
        databaseStrategy: 									# 数据库分片策略							
          complex:											# 有三种 standard,complex hint
            # 这里要是standard,则为shardingColumn
            shardingColumns: id 							# 使用 id 作为分片键
            shardingAlgorithmName: database_inline 			# 这是一个算法名称,在下面shardingAlgorithms下定义的
        tableStrategy: 										# 数据表分片策略
          complex:											# 这里要是standard,则为shardingColumn            
            shardingColumns: id  
            shardingAlgorithmName: con_file_upload_inline
    shardingAlgorithms:
      database_inline: 										# 自定义的算法名称,上边有用到
        type: CLASS_BASED
        props:
          # 分片策略类型,支持 STANDARD、COMPLEX 或 HINT(不区分大小写)
          strategy: COMPLEX
          # 分片算法全限定名
          algorithmClassName: org.apache.shardingsphere.custom.algorithm.TianYiDatabaseComplexKeysShardingAlgorithm
      con_file_upload_inline:
        type: CLASS_BASED
        props:
          # 分片策略类型,支持 STANDARD、COMPLEX 或 HINT(不区分大小写)
          strategy: COMPLEX
          # 分片算法全限定名
          algorithmClassName: org.apache.shardingsphere.custom.algorithm.TianYiTableComplexKeysShardingAlgorithm

3.2.不同数据库配置

分库分表策略一旦确定,几乎不会改变,那么集成不同数据库的配置差异主要在数据库连接配置,下面针对不同的数据库,说明其连接配置以及需要注意的事项。

3.2.1.mysql
1.依赖
<dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-spring-boot3-starter</artifactId>
            <version>3.5.4.1</version>
            <exclusions>
                <exclusion>
                	<!--这里排除是因为该版本的与springboot 3.2.0不兼容-->
                    <artifactId>mybatis-spring</artifactId>
                    <groupId>org.mybatis</groupId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>3.0.3</version>
        </dependency>
        
        <dependency>
            <groupId>org.apache.shardingsphere</groupId>
            <artifactId>shardingsphere-jdbc</artifactId>
            <version>5.5.2</version>
        </dependency>
		
		 <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <version>8.3.0</version>
        </dependency>
2.配置
...

dataSources:
  ds1:
    dataSourceClassName: com.alibaba.druid.pool.DruidDataSource
    driverClassName: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://192.168.245.128:3306/test?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&allowMultiQueries=true&rewriteBatchedStatements=true
    username: xxx
    password: xxx
  ds2:
    dataSourceClassName: com.alibaba.druid.pool.DruidDataSource
    driverClassName: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://192.168.245.128:3306/test1?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&allowMultiQueries=true&rewriteBatchedStatements=true
    username: xxx
    password: xxx
...
3.2.2.kingbase

目前shardingsphere-jdbc不支持kingbase的分库分表,平台组参考官方源码写了一个kingbase的适配模块,项目中集成该模块,便可实现针对kingbase的分库分表。

1.依赖
 		<dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-spring-boot3-starter</artifactId>
            <version>3.5.4.1</version>
            <exclusions>
                <exclusion>
                	<!--这里排除是因为该版本的与springboot 3.2.0不兼容-->
                    <artifactId>mybatis-spring</artifactId>
                    <groupId>org.mybatis</groupId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>3.0.3</version>
        </dependency>
        
        <dependency>
            <groupId>org.apache.shardingsphere</groupId>
            <artifactId>shardingsphere-jdbc</artifactId>
            <version>5.5.2</version>
        </dependency>

 		<dependency>
            <groupId>org.apache.shardingsphere</groupId>
            <artifactId>shardingsphere-infra-database-kingbase</artifactId>
            <version>2.1.4-sharding</version>
        </dependency>

        <dependency>
            <groupId>org.apache.shardingsphere</groupId>
            <artifactId>shardingsphere-parser-sql-kingbase</artifactId>
            <version>2.1.4-sharding</version>
        </dependency>

        <dependency>
            <groupId>org.apache.shardingsphere</groupId>
            <artifactId>shardingsphere-parser-sql-statement-kingbase</artifactId>
            <version>2.1.4-sharding</version>
        </dependency>

        <dependency>
            <groupId>org.apache.shardingsphere</groupId>
            <artifactId>shardingsphere-infra-database-algorithm</artifactId>
            <version>2.1.4-sharding</version>
        </dependency>
        
 		<dependency>
            <groupId>cn.com.kingbase</groupId>
            <artifactId>kingbase8</artifactId>
            <version>8.6.0</version>
        </dependency>
2.配置

sharding.yml

...

dataSources:
  ds1:
    dataSourceClassName: com.alibaba.druid.pool.DruidDataSource
    driverClassName: com.kingbase8.Driver
    url: jdbc:kingbase8://192.168.245.128:54321/test?currentSchema=tianyi&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&allowMultiQueries=true&nullCatalogMeansCurrent=true
    username: xxx
    password: xxx
  ds2:
    dataSourceClassName: com.alibaba.druid.pool.DruidDataSource
    driverClassName: com.kingbase8.Driver
    url: jdbc:kingbase8://192.168.245.128:54321/test1?currentSchema=tianyi&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&allowMultiQueries=true&nullCatalogMeansCurrent=true
    username: xxx
    password: xxx
...
3.注意事项

数据库的连接参数数currentSchema有时不生效,导致找不到表,程序会报错。

url: jdbc:kingbase8://192.168.245.128:54321/test1?currentSchema=tianyi&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&allowMultiQueries=true&nullCatalogMeansCurrent=true

请使用如下方式设置数据库的默认模式:

方式一:

修改数据库的search_path

#修改数据库test的schema搜索路径为"$user", 'tianyi', public, sys, sys_catalog, pg_catalog
ALTER DATABASE "test" SET search_path to "$user", 'tianyi', public, sys, sys_catalog, pg_catalog;

#修改完成之后查看是否修改成功
SHOW search_path;

方式二:

在currentSchema后列举所有可能查到的schema

url: jdbc:kingbase8://192.168.245.128:54321/test1?currentSchema=tianyi,public,sys,sys_catelog&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&allowMultiQueries=true&nullCatalogMeansCurrent=true

注意:两种方式不要混用

4.参考

一口气搞懂分库分表 12 种分片算法,大厂都在用

使用shardingsphere进行分库分表

Spring Boot使用 ShardingSphere + MyBatis + Druid 进行分库分表

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐