行表达式

实现动机

配置的简化与一体化是行表达式所希望解决的两个主要问题。

在繁琐的数据分片规则配置中,随着数据节点的增多,大量的重复配置使得配置本身不易被维护。 通过行表达式可以有效地简化数据节点配置工作量。

对于常见的分片算法,使用 Java 代码实现并不有助于配置的统一管理。 通过行表达式书写分片算法,可以有效地将规则配置一同存放,更加易于浏览与存储。

语法说明

行表达式的使用非常直观,只需要在配置中使用 ${ expression }$->{ expression } 标识行表达式即可。 目前支持数据节点和分片算法这两个部分的配置。 行表达式的内容使用的是 Groovy 的语法,Groovy 能够支持的所有操作,行表达式均能够支持。 例如:

${begin..end} 表示范围区间

${[unit1, unit2, unit_x]} 表示枚举值

行表达式中如果出现连续多个 ${ expression }$->{ expression } 表达式,整个表达式最终的结果将会根据每个子表达式的结果进行笛卡尔组合。

例如,以下行表达式:

  1. ${['online', 'offline']}_table${1..3}

最终会解析为:

  1. online_table1, online_table2, online_table3, offline_table1, offline_table2, offline_table3

配置

数据节点

对于均匀分布的数据节点,如果数据结构如下:

  1. db0
  2. ├── t_order0
  3. └── t_order1
  4. db1
  5. ├── t_order0
  6. └── t_order1

用行表达式可以简化为:

  1. db${0..1}.t_order${0..1}

或者

  1. db$->{0..1}.t_order$->{0..1}

对于自定义的数据节点,如果数据结构如下:

  1. db0
  2. ├── t_order0
  3. └── t_order1
  4. db1
  5. ├── t_order2
  6. ├── t_order3
  7. └── t_order4

用行表达式可以简化为:

  1. db0.t_order${0..1},db1.t_order${2..4}

或者

  1. db0.t_order$->{0..1},db1.t_order$->{2..4}

对于有前缀的数据节点,也可以通过行表达式灵活配置,如果数据结构如下:

  1. db0
  2. ├── t_order_00
  3. ├── t_order_01
  4. ├── t_order_02
  5. ├── t_order_03
  6. ├── t_order_04
  7. ├── t_order_05
  8. ├── t_order_06
  9. ├── t_order_07
  10. ├── t_order_08
  11. ├── t_order_09
  12. ├── t_order_10
  13. ├── t_order_11
  14. ├── t_order_12
  15. ├── t_order_13
  16. ├── t_order_14
  17. ├── t_order_15
  18. ├── t_order_16
  19. ├── t_order_17
  20. ├── t_order_18
  21. ├── t_order_19
  22. └── t_order_20
  23. db1
  24. ├── t_order_00
  25. ├── t_order_01
  26. ├── t_order_02
  27. ├── t_order_03
  28. ├── t_order_04
  29. ├── t_order_05
  30. ├── t_order_06
  31. ├── t_order_07
  32. ├── t_order_08
  33. ├── t_order_09
  34. ├── t_order_10
  35. ├── t_order_11
  36. ├── t_order_12
  37. ├── t_order_13
  38. ├── t_order_14
  39. ├── t_order_15
  40. ├── t_order_16
  41. ├── t_order_17
  42. ├── t_order_18
  43. ├── t_order_19
  44. └── t_order_20

可以使用分开配置的方式,先配置包含前缀的数据节点,再配置不含前缀的数据节点,再利用行表达式笛卡尔积的特性,自动组合即可。 上面的示例,用行表达式可以简化为:

  1. db${0..1}.t_order_0${0..9}, db${0..1}.t_order_${10..20}

或者

  1. db$->{0..1}.t_order_0$->{0..9}, db$->{0..1}.t_order_$->{10..20}

分片算法

对于只有一个分片键的使用 =IN 进行分片的 SQL,可以使用行表达式代替编码方式配置。

行表达式内部的表达式本质上是一段 Groovy 代码,可以根据分片键进行计算的方式,返回相应的真实数据源或真实表名称。

例如:分为 10 个库,尾数为 0 的路由到后缀为 0 的数据源, 尾数为 1 的路由到后缀为 1 的数据源,以此类推。用于表示分片算法的行表达式为:

  1. ds${id % 10}

或者

  1. ds$->{id % 10}