【经验分享】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

为实现复数类的++ --运算,我们需要对复数类进运算符重载。我们可以重载前置++和--运算符和后置++和--运算符。 下面是一个简单的复数类的定义: ```cpp class Complex { private: double real_; double imag_; public: Complex(double real = 0, double imag = 0) : real_(real), imag_(imag) {} double real() const { return real_; } double imag() const { return imag_; } Complex operator++(); //前置++ Complex operator--(); //前置-- Complex operator++(int); //后置++ Complex operator--(int); //后置-- }; Complex Complex::operator++() { real_++; imag_++; return *this; } Complex Complex::operator--() { real_--; imag_--; return *this; } Complex Complex::operator++(int) { Complex temp(*this); real_++; imag_++; return temp; } Complex Complex::operator--(int) { Complex temp(*this); real_--; imag_--; return temp; } ``` 前置++和--运算符直接将实部和虚部分别加/减1即可。 后置++和--运算符需要先保存当前对象的值,然后再将实部和虚部分别加/减1,最后返回保存的对象值。 下面是一个使用复数类的示例: ```cpp int main() { Complex a(1, 2); Complex b = ++a; Complex c = b--; cout << "a=" << a.real() << "+" << a.imag() << "i" << endl; cout << "b=" << b.real() << "+" << b.imag() << "i" << endl; cout << "c=" << c.real() << "+" << c.imag() << "i" << endl; return 0; } ``` 输出结果为: ``` a=2+3i b=2+3i c=3+4i ``` 可以看到,前置++和后置--运算符都可以正常工作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Xcong_Zhu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值