【经验分享】ShardingSphere+Springboot-03 : COMPLEX_INLINE 复杂行表达式分片算法

3.3 复杂分片算法

3.3.1 COMPLEX_INLINE 复杂行表达式分片算法

复合分片比较灵活,适合于分片的字段比较多,分片比较复杂的场景,使用这种分片的话必须对自己的业务比较明确

属性名称数据类型说明默认值
sharding-columns (?)String分片列名称,多个列用逗号分隔。如不配置无法则不能校验
algorithm-expressionString分片算法的行表达式
allow-range-query-with-inline-sharding (?)boolean是否允许范围查询。注意:范围查询会无视分片策略,进行全路由false

这样看官方文档还是写的不够详细,举个例子,创建一个用户表结构如下,分别是数据源ds1/ds2中分别创建以下两张表

image-20240809090636371

实现目标:根据用户类型user_type和部门dep_id进行复杂分库分表

配置yaml如下:

spring:
  shardingsphere:
    rules:
      sharding:
        tables:
          # 用户表
          sys_user:
            actual-data-nodes: ds${0..1}.sys_user_${0..1}
            key-generate-strategy:
              column: id
              key-generator-name: snowflake
            database-strategy:
              standard:
                sharding-algorithm-name: id_db_algorithm
                sharding-column: id
            table-strategy:
              # 注意:声明为复杂算法
              complex:
                # 指定参与复杂算法的分片列
                sharding-columns: user_type,dep_id
                sharding-algorithm-name: user_type_dep_id_algorithm
        # 配置分片算法
        sharding-algorithms:
          id_db_algorithm:
            type: INLINE
            props:
              algorithm-expression: ds$->{id % 2}
          user_type_dep_id_algorithm:
            # 指定类型为复杂行算法
            type: COMPLEX_INLINE
            props:
              # 依然是使用groovy表达式
              algorithm-expression: 'sys_user_$->{((user_type.isInteger() ? user_type.toInteger() : 0) + dep_id) % 2}'

配置解释

  1. 分片表的相关配置不再赘述,需要注意的是复杂算法需要去标准算法区分声明为complex
  2. 该配置中分库还是用简单行表达式,也不再赘述
  3. 算法声明
    • 算法的类型为 复杂行表达式算法
    • 表达式依然用使用groovy表达式,可以借助AI帮忙生成
    • 配置中表达式是根据user_type加上dep_id后取模进行计算得到

进行测试:

测试一:随机生成用户并插入数据库,打印出来插入对象和预测结果,和实际插入的真实表对比

image-20240809103624692

image-20240809103742849

测试二:查询条件带有user_type和dep_id,测试分表逻辑是否生效

image-20240809105337260