全部產品
Search
文件中心

:配置路由演算法

更新時間:Oct 18, 2024

本文介紹路由演算法配置的格式,及如何為邏輯表配置路由演算法。

背景資訊

路由演算法是減少路由時開銷的一種演算法,邏輯表配置了路由演算法後,帶路由欄位則可以快速查詢指定物理表,免去人為計算、切換物理庫表的操作。

路由演算法的更多資訊,請參見路由演算法

使用情境

  • 分表資料查詢
  • 分表資料變更
  • 分表資料匯出

配置說明

Data Management分表路由演算法採用Groovy運算式方式定義,與應用代碼裡使用配置的路由演算法類似。

運算式格式:#+路由欄位+#。例如#shardKey#

配置路由演算法

如下操作展示如何配置簡單模數方式的路由演算法。

  1. 在邏輯庫下配置邏輯表。具體操作,請參見邏輯表

  2. 邏輯表配置完成後,您可在全域搜尋網頁面單擊目標邏輯庫右側的查詢,進入SQL視窗頁面。

    說明

    您也可以在頂部功能表列中,選擇SQL視窗 > SQL視窗

  3. 在頁面右上方單擊image.png ,進入表列表頁面。

  4. 單擊目標邏輯錶行的配置演算法

  5. 在演算法列表頁面,單擊新增,配置演算法類型模數方式分表欄位模數

    本樣本中的演算法類型選擇單列模數、模數方式選擇簡單模數,分表欄位選擇id,模數為4,運算式為#id#%4

    說明
    • 簡單模數只能選中數字類型的欄位進行模數。

    • 雜湊模數可選擇數字或者字串類型的欄位進行模數。

  6. 單擊儲存

  7. 路由演算法配置完成後,您可在邏輯表中查詢表資料、執行INSERT語句。系統會根據計算的路由結果,將資料插入對應編號的分表中。

    例如插入一個ID為9的資料行,其計算的路由結果為1,該資料將會插入logic_table_01分表中。

    image.png

路由運算式樣本

如下運算式中的user_id為表欄位樣本值。

  • 按表規則路由

    • 簡單模數

      • 數字模數:#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)

      • 字串的第16、17位元字除以2路由庫,字串的第16、17位路由表:'schema_prefix_'+substring(#EXTEND_ID#,16,18).toLong().intdiv(2)+'.table_name_prefix_'+substring(#EXTEND_ID#,16,18)

  • 按日期路由

    每月同一天路由到同一個表: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#)
    說明
    • 函數與運算式之間需要設定換行。

    • DMS支援CRC32(java.util.zip.CRC32)函數路由。

內建通用函數

  • cobarOldHash

    舊的CorbarHash演算法

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

    新的cobarHash演算法

    public static long cobarHash(String s, int start, int end) {
      if (start < 0) {
          start = 0;
      }
      if (end > s.length()) {
          end = s.length();
      }
      long h = 0;
      for (int i = start; i < end; ++i) {
          h = (h << 5) - h + s.charAt(i);
      }
      return h;
    }
  • weekOfYear

    該演算法展示一年中的第幾個周資訊

    public static int weekOfYear(String dateValue) {
      Date date = DateTimeUtils.getSomeDate(dateValue);
      if(date != null) {
          return DateTimeUtils.getWeekOfYear(date);
      }
    
      return 0;
    }
  • dayOfYear

    該演算法展示一年中的天資訊

    public static int dayOfYear(String dateValue) {
      Date date = DateTimeUtils.getSomeDate(dateValue);
      if(date != null) {
          return DateTimeUtils.getDayOfYear(date);
      }
    
      return 0;
    }
  • dayOfMonth

    該演算法展示月中的天資訊

    public static int dayOfMonth(String dateValue) {
      Date date = DateTimeUtils.getSomeDate(dateValue);
      if (date != null) {
          return DateTimeUtils.getDayOfMonth(date);
      }
      return 0;
    }
  • dayOfWeek

    該演算法展示周中的天資訊

    public static int dayOfWeek(String dateValue) {
      Date date = DateTimeUtils.getSomeDate(dateValue);
      if (date != null) {
          int dayOfWeek = DateTimeUtils.getDayOfWeek(date);
          if (dayOfWeek==1){
              dayOfWeek=7;
          }else {
              dayOfWeek=dayOfWeek-1;
          }
          return dayOfWeek;
      }
      return 0;
    }
  • substring

    該演算法可截取長度資訊,開始和結束支援為負數,表示方向從後往前

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

    該演算法可截取長度資訊,從什麼位置開始

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

    該演算法可取字串後四位,不足四位在左邊補0,最後四位每兩位自動對換

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

    該演算法可擷取指定最小長度的字串,若長度不足則會在數字前補0

    public static String lastSwapZero(String value, int length) {
      if (value.length() < length) {
          return StringUtils.leftPad(value, length, '0');
      }
      return value;
    }