すべてのプロダクト
Search
ドキュメントセンター

:ルーティングアルゴリズムの設定

最終更新日:Aug 16, 2024

このトピックでは、ルーティング式の形式と、論理テーブルのルーティングアルゴリズムを設定する方法について説明します。

概要

論理テーブルのルーティングアルゴリズムを設定して、ルーティングフィールドに基づいて論理テーブルと一致する特定の物理テーブルのデータを効率的にクエリできます。 この方法では、手動計算を実行したり、物理テーブルを切り替えたりする必要はありません。 これにより、ルーティングのオーバーヘッドが低減される。

詳細については、「ルーティングアルゴリズム」をご参照ください。

シナリオ

  • テーブルシャードのデータを照会します。

  • テーブルシャードのデータを変更します。

  • テーブルシャードのデータをエクスポートします。

式の形式

データ管理 (DMS) では、Groovy式を使用してテーブルシャードをクエリするためのルーティングアルゴリズムを定義できます。 ルーティング式の形式は、アプリケーションコードで使用される形式と似ています。

ルーティングフィールドは、# ルーティングフィールド# の形式で指定できます。 例: #shardKey#

手順

以下の例では、ルーティングアルゴリズムは、単純なモジュロ演算を実行するように構成される。

  1. 論理データベースに論理テーブルを作成します。 詳細については、「論理テーブル」をご参照ください。

  2. 論理テーブルを設定したら、[グローバル検索] ページで論理データベースを見つけます。 次に、[操作] 列の [クエリ] をクリックして、[SQLコンソール] ページに移動します。

    説明

    上部のナビゲーションバーで [SQLコンソール] > [SQLコンソール] を選択することもできます。 次に、ドロップダウンリストから論理データベースを選択して、[SQLコンソール] ページに移動します。

  3. ページの右上隅にあるアイコンをクリックしimage.pngて、テーブルリストページに移動します。

  4. 作成した論理テーブルを見つけます。 次に、[ルーティングアルゴリズム] 列の [アルゴリズムの設定] をクリックします。

  5. 表示されるページで、[作成] をクリックします。 [アルゴリズムの作成] ダイアログボックスで、[アルゴリズムの種類][モジュロ演算][テーブルパーティショニングフィールド] 、および [モジュラス] パラメーターを設定します。

    この例では、Modulo Operation on One Columnがアルゴリズムタイプとして選択され、Simple Modulo OperationがModulo Operationとして選択され、idがTable Partitioning Fieldとして選択され、Modulusパラメータが4に設定される。 ルーティングアルゴリズムの式は #id#% 4です。

    説明
    • 単純なモジュロ演算は、数値フィールドに対してのみ実行できます。

    • 数値フィールドと文字列フィールドの両方でモジュラハッシュ演算を実行できます。

  6. [保存] をクリックします。

  7. ルーティングアルゴリズムの設定後、論理テーブルのデータを照会し、INSERTステートメントを実行します。 システムは、ルーティングアルゴリズムを使用して計算された結果に基づいて、対応するテーブルシャードにデータを挿入します。

    たとえば、ID列の値が9のデータ行を挿入すると、ルーティング結果は1になり、そのデータ行は名前がlogic_table_01のテーブルシャードに挿入されます。

サンプルルーティング式

次のルーティング式のサンプルでは、user_idは論理テーブルのフィールドです。

  • テーブルシャーディングに基づくルーティング

    • 単純なモジュロ演算

      • 数値フィールドのモジュロ演算: #user_id#% 100

      • 2次モジュロ演算: #user_id#% 10000% 100

      • 数値フィールドのJavaハッシュコードに対するモジュロ演算: Math.abs(#user_id#.hashCode())% 100

    • 文字列フィールドのモジュロ演算

      • 数値文字列ハッシュ: Math.abs(#user_id#.toString().hashCode())% 100

      • 文字列ハッシュ: 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)

      • EXTEND_IDフィールドの16文字目と7文字目で構成される整数を2で割って名前が決定されるデータベースと、EXTEND_IDフィールドの16文字目と7文字目で構成される整数で名前が決定されるテーブルにデータをルーティングします。'schema_prefix_'+ 部分文字列 (#EXTEND_ID# 、16,18).toLong().intdiv(2)+'.table_name_prefix_'+ 部分文字列 (#EXTEND_ID# 、16,18)

  • 日付に基づくルーティング

    毎月同じ日にデータを同じテーブルにルーティングします。dayOfMonth(#time#)

  • 文字列フィールドの最後から3番目の文字に基づくルーティング

    Integer.valueOf(substring(#ip_id#,-3,-2))* 10: テーブル名のインデックス値が10増加した場合、ip_idフィールドの最後から3番目の文字から変換された整数に10を掛けます。 テーブル名のインデックス値が1増加した場合、ip_idフィールドの最後から3番目の文字から変換された整数は10倍されません。

  • その他の複雑なルーティング方法

    ユーザー定義関数 (UDF) を使用してデータをルーティングする: String func(String arg){ return arg.hashCode()% 10;} 'table_name_'+ func(#user_id#)+'_other_'func(#user_id#)

    Groovy構文の詳細については、「Groovy」をご参照ください。

一般的な組み込み関数

  • 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;
    }
  • 部分文字列

    文字列フィールドを切り捨て、部分文字列を返します。 開始パラメータおよび終了パラメータの値は、負であり得る。 この場合、位置は逆算される。

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

    文字列フィールドを切り捨て、部分文字列を返します。 startパラメーターは、切り捨ての開始位置を指定します。

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

    文字列フィールドの最後の4文字で構成される部分文字列を返します。 stringフィールドの値の長さが4文字でない場合、値の左側に特定の数の0がパディングされ、値に4文字が含まれます。 最後の4番目と3番目の文字の位置を最後の2文字と交換して部分文字列を形成します。

    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

    文字列フィールドの最後の文字列の部分文字列を返します。 lengthパラメーターは、返す文字数を指定します。 文字列フィールドの値が指定された長さより短い場合、値の左側に特定の数の0がパディングされ、値に指定された長さの文字が含まれます。

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