全部产品
云市场

路由算法配置

更新时间:2019-02-15 15:07:00

路由算法配置

分表路由

  • DMS企业版分表路由算法采用Groovy表达式方式定义,和应用代码里使用配置的路由算法类似

格式

  • #shardKey#,即“#”+路由字段+“#”为一个完整的表达式

典型案例

  • 按表路由
    • 简单取摸
      • 数字取摸 #user_id#%100
      • 二次取摸 #user_id#%10000%100
      • 数字JavaHash取摸 Math.abs(#user_id#.hashCode())%100
    • 字符串取摸
      • 数字字符串hash Math.abs(#user_id#.toString().hashCode())%100
      • 字符串hash Math.abs(#user_id#.hashCode())%100
      • CobarHash Math.abs(cobarHash(#column#,start, end)).intdiv(8)
      • CobarOldHash Math.abs(cobarOldHash(#column#, len)).intdiv(8)
  • 按库规则路由
    • 同名表库名规则 ‘schema_prefix_‘+(#user_id#%10)+’.table_name’
    • 库名和表名
      • ‘schema_prefix_‘+(#user_id#%100)+’.table_name_prefix_‘+(#user_id#%1000)
      • ‘schema_prefix_‘+lastSwapZero(String.valueOf((#user_id#%1024).intdiv(128),4)+’.table_name_prefix_‘+lastSwapZero(String.valueOf((#user_id#%128)),4) 每个分库内同一套分表
      • ‘schema_prefix_‘+substring(#EXTEND_ID#,16,18).toLong().intdiv(2)+’.table_name_prefix_‘+substring(#EXTEND_ID#,16,18) 字符串的第16、17位数字除以2路由库,字符串的第16、17位路由表
  • 按日期路由
    • 每月同一天路由到同一个表 dayOfMonth(#time#)
  • 按照字符串的倒数第三位进行路由
    • 表名步长为10递增乘以10,若为1则不需要乘Integer.valueOf(substring(#ip_id#,-3,-2))*10
  • 其它复杂路由
    • 自定义函数方式 【String func(String arg){ return arg.hashCode()%10;} ‘table_name_‘+func(#user_id#)+’_other_‘func(#user_id#)】
  • Groovy学习参考 Groovy

内置通用函数

  • cobarOldHash

    • 算法说明:老的corbarHash算法

      1. public static long cobarOldHash(String s, int len) {
      2. long h = 0;
      3. int sLen = s.length();
      4. for (int i = 0; (i < len && i < sLen); i++) {
      5. h = (h << 5) - h + s.charAt(i);
      6. }
      7. return h;
      8. }
  • cobarHash

    • 算法说明:新的cobarHash

      1. public static long cobarHash(String s, int start, int end) {
      2. if (start < 0) {
      3. start = 0;
      4. }
      5. if (end > s.length()) {
      6. end = s.length();
      7. }
      8. long h = 0;
      9. for (int i = start; i < end; ++i) {
      10. h = (h << 5) - h + s.charAt(i);
      11. }
      12. return h;
      13. }
  • weekOfYear

    • 算法说明:一年中的第几个周信息

      1. public static int weekOfYear(String dateValue) {
      2. Date date = DateTimeUtils.getSomeDate(dateValue);
      3. if(date != null) {
      4. return DateTimeUtils.getWeekOfYear(date);
      5. }
      6. return 0;
      7. }
  • dayOfYear

    • 算法说明:一年中的天信息

      1. public static int dayOfYear(String dateValue) {
      2. Date date = DateTimeUtils.getSomeDate(dateValue);
      3. if(date != null) {
      4. return DateTimeUtils.getDayOfYear(date);
      5. }
      6. return 0;
      7. }
  • dayOfMonth

    • 算法说明:月中的天信息

      1. public static int dayOfMonth(String dateValue) {
      2. Date date = DateTimeUtils.getSomeDate(dateValue);
      3. if (date != null) {
      4. return DateTimeUtils.getDayOfMonth(date);
      5. }
      6. return 0;
      7. }
  • dayOfWeek

    • 算法说明:周中的天信息

      1. public static int dayOfWeek(String dateValue) {
      2. Date date = DateTimeUtils.getSomeDate(dateValue);
      3. if (date != null) {
      4. int dayOfWeek = DateTimeUtils.getDayOfWeek(date);
      5. if (dayOfWeek==1){
      6. dayOfWeek=7;
      7. }else {
      8. dayOfWeek=dayOfWeek-1;
      9. }
      10. return dayOfWeek;
      11. }
      12. return 0;
      13. }
  • substring

    • 算法说明:截取长度信息,开始和结束支持为负数,表示方向从后向前

      1. public static String substring(String value, int start, int end) {
      2. return StringUtils.substring(value, start, end);
      3. }
  • substring

    • 算法说明:截取长度,从什么位置开始

      1. public static String substring(String value, int start) {
      2. return StringUtils.substring(value, start);
      3. }
  • last4swap

    • 算法说明:取长度最后四位,不足四位左边补0,然后最后四位每两位自动对换

      1. public static String last4swap(String value) {
      2. if(value.length() < 4) {
      3. value = StringUtils.leftPad(value, 4, '0');
      4. }
      5. return StringUtils.substring(value, -2)+StringUtils.substring(value, -4, -2);
      6. }
  • lastSwapZero

    • 算法说明:截取指定长度的字符串 如长度不足在数字前补0

      1. public static String lastSwapZero(String value, int length) {
      2. if (value.length() < length) {
      3. return StringUtils.leftPad(value, length, '0');
      4. }
      5. return value;
      6. }