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

PolarDB:CREATE TABLE (DRDS モード)

最終更新日:Mar 28, 2026

DRDS モードでは、PolarDB-X が標準 MySQL の CREATE TABLE 文を拡張し、データベースシャーディング、テーブルシャーディング、グローバルセカンダリインデックス (GSI)、シャドウテーブル、およびストレージのローカリティを指定する句を追加しています。本トピックでは、拡張された構文について説明し、各テーブルタイプの使用例を示します。

Standard Edition では、データベースシャーディングおよびテーブルシャーディングの構文はサポートされていません。

構文

CREATE [SHADOW] TABLE [IF NOT EXISTS] tbl_name
    (create_definition, ...)
    [table_options]
    [drds_partition_options]

create_definition:
    col_name column_definition
  | mysql_create_definition
  | [UNIQUE] GLOBAL INDEX index_name [index_type] (index_sharding_col_name,...)
      [global_secondary_index_option]
      [index_option] ...

-- GSI オプション
global_secondary_index_option:
    [COVERING (col_name,...)]
    [drds_partition_options]
    [VISIBLE|INVISIBLE]

-- データベースおよびテーブルのシャーディング句
drds_partition_options:
    DBPARTITION BY db_sharding_algorithm
    [TBPARTITION BY table_sharding_algorithm [TBPARTITIONS num]]
    [LOCALITY=locality_option]

db_sharding_algorithm:
    HASH([col_name])
  | {YYYYMM|YYYYWEEK|YYYYDD|YYYYMM_OPT|YYYYWEEK_OPT|YYYYDD_OPT}(col_name)
  | UNI_HASH(col_name)
  | RIGHT_SHIFT(col_name, n)
  | RANGE_HASH(col_name, col_name, n)

table_sharding_algorithm:
    HASH(col_name)
  | {MM|DD|WEEK|MMDD|YYYYMM|YYYYWEEK|YYYYDD|YYYYMM_OPT|YYYYWEEK_OPT|YYYYDD_OPT}(col_name)
  | UNI_HASH(col_name)
  | RIGHT_SHIFT(col_name, n)
  | RANGE_HASH(col_name, col_name, n)

-- 非シャーディングテーブルのストレージ場所
locality_option:
    'dn=storage_inst_id_list'

storage_inst_id_list:
    storage_inst_id[,storage_inst_id_list]

-- MySQL DDL 構文
index_sharding_col_name:
    col_name [(length)] [ASC | DESC]

index_option:
    KEY_BLOCK_SIZE [=] value
  | index_type
  | WITH PARSER parser_name
  | COMMENT 'string'

index_type:
    USING {BTREE | HASH}
PolarDB-X の DDL 構文は MySQL 構文に基づいています。本トピックでは、拡張機能および差分点のみを説明します。完全な MySQL DDL 構文については、「MySQL ドキュメント」をご参照ください。

MySQL との違い

DRDS モードの PolarDB-X では、標準 MySQL には存在しない以下の拡張機能が導入されています。

拡張機能説明
DBPARTITION BY行を物理データベースシャード間でルーティングします
TBPARTITION BY各データベース シャード内のさらに細かいシャード化された行
TBPARTITIONS num各データベースシャード内の物理テーブル数を設定します
GLOBAL INDEXすべてのシャードにまたがるグローバルセカンダリインデックス (GSI) を定義します
UNIQUE GLOBAL INDEXすべてのシャード全体で一意性が保証される GSI を定義します
COVERING (col_name,...)GSI インデックステーブルに格納する追加の列を指定します
LOCALITY非シャーディングテーブルを特定のデータノードに固定します
SHADOWエンドツーエンドストレステスト用のシャドウテーブルを作成します
Standard Edition では、DBPARTITION BY および TBPARTITION BY はサポートされていません。

シャーディング句およびパラメーター

説明
DBPARTITION BY hash(col)指定した列のハッシュ値を用いて、データをデータベースシャード間でシャーディングしますDBPARTITION BY hash(id)
TBPARTITION BY hash(col)任意指定。指定した列のハッシュ値を用いて、各データベースシャード内でデータをシャーディングします。DBPARTITION BY が省略された場合、デフォルトで同様の動作となりますTBPARTITION BY hash(bid)
TBPARTITION BY MM(col)各データベース シャード内のシャード(年の月ごと:1~12)TBPARTITION BY MM(actionDate)
TBPARTITION BY DD(col)各データベースシャード内のシャード (月の日付 (1~31) ごと)TBPARTITION BY DD(actionDate)
TBPARTITION BY WEEK(col)週間の曜日 (1–7) に基づいて、各データベースシャード内でシャーディングしますTBPARTITION BY WEEK(actionDate)
TBPARTITION BY MMDD(col)年間の日 (1–365) に基づいて、各データベースシャード内でシャーディングしますTBPARTITION BY MMDD(actionDate)
TBPARTITIONS num任意指定。各データベースシャード内の物理テーブル数です。デフォルト値:1TBPARTITIONS 3

シャーディング関数の完全な一覧については、「シャーディング関数」をご参照ください。

GSI 句およびパラメーター

説明
[UNIQUE] GLOBAL INDEX index_nameGSI を定義します。UNIQUE GLOBAL INDEX では、データベース全体でインデックス列の一意性が保証されます
index_nameGSI の名前です。インデックステーブルには同じ名前が使用されます
index_typeインデックステーブル内のシャードキー上のローカルインデックスのタイプ。MySQL ドキュメント
index_sharding_col_nameインデックス列であり、インデックステーブルのシャードキー列です
COVERING (col_name,...)インデックス列に加えて、インデックステーブルに格納されるカバリング列です。デフォルトでは、ベーステーブルのプライマリキー列およびシャードキー列が含まれます
drds_partition_optionsインデックステーブルのシャーディング句です。ベーステーブルと同じ構文を使用します
index_optionシャードキーに対するローカルインデックスの属性です。「MySQL ドキュメント

グローバルセカンダリインデックスの詳細については、「グローバルセカンダリインデックスの使用方法」をご参照ください。

SHADOW 句

SHADOW は、エンドツーエンドストレステスト用のシャドウテーブルを作成します。シャドウテーブル名には以下のルールが適用されます。

  • 名前には _test_ をプレフィックスとして使用する必要があります。

  • プレフィックス後の部分は、関連付けられた正式なテーブル名と完全に一致する必要があります。

  • シャドウテーブルを作成する前に、正式なテーブルが存在している必要があります。

LOCALITY 句

LOCALITY は、非シャーディングテーブルを作成時に特定のデータノードに固定します。

LOCALITY='dn=storage_inst_id_list'

使用上の注意点:

  • LOCALITY を使用してストレージ場所を指定した後は、変更できません。

  • 非シャーディングテーブルのストレージ場所は、データベースのストレージ場所とは独立しています。

  • PolarDB-X インスタンスで非シャーディングテーブルを作成する際に LOCALITY を指定しなかった場合、テーブルはランダムなデータノードに配置されます。その後、場所を指定せずに作成された非シャーディングテーブルは、同一のデータノードに配置されます。

使用例

以下の使用例では、8 つのデータベースシャードを持つ PolarDB-X インスタンスを想定しています。

非シャーディングテーブルの作成

非シャーディングテーブルは、単一の物理場所に格納される論理テーブルです。データをシャード間で分散する必要がない場合に使用します。

CREATE TABLE single_tbl(
  id bigint not null auto_increment,
  name varchar(30),
  primary key(id)
);

SHOW TOPOLOGY を使用して、テーブルの配置を確認します。

SHOW TOPOLOGY FROM single_tbl;
+------+------------------------------------------------------------------+------------+
| ID   | GROUP_NAME                                                       | TABLE_NAME |
+------+------------------------------------------------------------------+------------+
|    0 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0000_RDS | single_tbl |
+------+------------------------------------------------------------------+------------+
1 row in set (0.01 sec)

結果から、テーブルが単一のデータベースシャード(データベース 0)に配置されていることが確認できます。

テーブルを特定のデータノードに固定するには、作成時に LOCALITY を指定します。次の例では、テーブルを db1 に作成し、polardbx-storage-0-master 上に格納します。これは、db1 データベースのデフォルトノードとは異なります。

CREATE TABLE tb1 (id int) LOCALITY='dn=polardbx-storage-0-master';

配置を確認します。

SHOW TOPOLOGY FROM tb1;
+----+------------------+------------+
| ID | GROUP_NAME       | TABLE_NAME |
+----+------------------+------------+
| 0  | DB1_000000_GROUP | tb1        |
+----+------------------+------------+
1 row in set
DB1_000000_GROUP シャードにより、テーブルが指定されたデータノード上に格納されていることが確認できます。

データベースシャーディングのみを実行するテーブルの作成

データベースシャーディングは、各シャード内でさらに分割することなく、複数のデータベースシャードにデータを分散します。データベース間での均等なディストリビューションで十分であり、各データベース内のデータ量が管理可能である場合に使用します。

CREATE TABLE multi_db_single_tbl(
  id bigint not null auto_increment,
  name varchar(30),
  primary key(id)
) DBPARTITION BY hash(id);

トポロジーを確認し、各データベースシャードに 1 つの物理テーブルが存在することを検証します。

SHOW TOPOLOGY FROM multi_db_single_tbl;
+------+------------------------------------------------------------------+---------------------+
| ID   | GROUP_NAME                                                       | TABLE_NAME          |
+------+------------------------------------------------------------------+---------------------+
|    0 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0000_RDS | multi_db_single_tbl |
|    1 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0001_RDS | multi_db_single_tbl |
|    2 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0002_RDS | multi_db_single_tbl |
|    3 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0003_RDS | multi_db_single_tbl |
|    4 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0004_RDS | multi_db_single_tbl |
|    5 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0005_RDS | multi_db_single_tbl |
|    6 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0006_RDS | multi_db_single_tbl |
|    7 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | multi_db_single_tbl |
+------+------------------------------------------------------------------+---------------------+
8 rows in set (0.01 sec)

データベースシャーディングおよびテーブルシャーディングを実行するテーブルの作成

各データベースシャード内でさらにデータを分割する必要がある場合は、TBPARTITION BY および TBPARTITIONS を追加します。PolarDB-X では、ハッシュベース、二重フィールドハッシュ、および日付ベースのテーブルシャーディングがサポートされています。

ハッシュベースのシャーディング

時間ベースのアクセスパターンがない場合に、行を均等に分散するためにハッシュベースのシャーディングを使用します。次の例では、id を使用して 8 つのデータベースシャードにデータを分散し、さらに bid を使用して各シャードを 3 つの物理テーブルに分割します。

CREATE TABLE multi_db_multi_tbl(
  id bigint not null auto_increment,
  bid int,
  name varchar(30),
  primary key(id)
) DBPARTITION BY hash(id) TBPARTITION BY hash(bid) TBPARTITIONS 3;

トポロジーを確認します。各データベースシャードに 3 つの物理テーブル、合計で 24 個のテーブルが存在します。

SHOW TOPOLOGY FROM multi_db_multi_tbl;
+------+------------------------------------------------------------------+-----------------------+
| ID   | GROUP_NAME                                                       | TABLE_NAME            |
+------+------------------------------------------------------------------+-----------------------+
|    0 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0000_RDS | multi_db_multi_tbl_00 |
|    1 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0000_RDS | multi_db_multi_tbl_01 |
|    2 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0000_RDS | multi_db_multi_tbl_02 |
|    3 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0001_RDS | multi_db_multi_tbl_03 |
|    4 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0001_RDS | multi_db_multi_tbl_04 |
|    5 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0001_RDS | multi_db_multi_tbl_05 |
|    6 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0002_RDS | multi_db_multi_tbl_06 |
|    7 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0002_RDS | multi_db_multi_tbl_07 |
|    8 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0002_RDS | multi_db_multi_tbl_08 |
|    9 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0003_RDS | multi_db_multi_tbl_09 |
|   10 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0003_RDS | multi_db_multi_tbl_10 |
|   11 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0003_RDS | multi_db_multi_tbl_11 |
|   12 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0004_RDS | multi_db_multi_tbl_12 |
|   13 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0004_RDS | multi_db_multi_tbl_13 |
|   14 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0004_RDS | multi_db_multi_tbl_14 |
|   15 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0005_RDS | multi_db_multi_tbl_15 |
|   16 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0005_RDS | multi_db_multi_tbl_16 |
|   17 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0005_RDS | multi_db_multi_tbl_17 |
|   18 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0006_RDS | multi_db_multi_tbl_18 |
|   19 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0006_RDS | multi_db_multi_tbl_19 |
|   20 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0006_RDS | multi_db_multi_tbl_20 |
|   21 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | multi_db_multi_tbl_21 |
|   22 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | multi_db_multi_tbl_22 |
|   23 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | multi_db_multi_tbl_23 |
+------+------------------------------------------------------------------+-----------------------+
24 rows in set (0.01 sec)

シャーディングルールを確認し、データベースおよびテーブルのパーティションキーとポリシーを検証します。

SHOW RULE FROM multi_db_multi_tbl;
+------+--------------------+-----------+------------------+---------------------+--------------------+------------------+---------------------+--------------------+
| ID   | TABLE_NAME         | BROADCAST | DB_PARTITION_KEY | DB_PARTITION_POLICY | DB_PARTITION_COUNT | TB_PARTITION_KEY | TB_PARTITION_POLICY | TB_PARTITION_COUNT |
+------+--------------------+-----------+------------------+---------------------+--------------------+------------------+---------------------+--------------------+
|    0 | multi_db_multi_tbl |         0 | id               | hash                | 8                  | bid              | hash                | 3                  |
+------+--------------------+-----------+------------------+---------------------+--------------------+------------------+---------------------+--------------------+
1 row in set (0.01 sec)

データベースおよびテーブルのシャーディングを、その他の MySQL テーブル属性と組み合わせることもできます。

CREATE TABLE multi_db_multi_tbl(
  id bigint not null auto_increment,
  name varchar(30),
  primary key(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 DBPARTITION BY hash(id) TBPARTITION BY hash(id) TBPARTITIONS 3;

二重フィールドハッシュシャーディング (RANGE_HASH)

クエリが 2 つのシャードキーのいずれかを指定して送信される可能性があり、両方とも同一の物理シャードにルーティングされる必要がある場合に、RANGE_HASH を使用します。一般的なシナリオとして、注文者 ID と注文 ID の両方でシャーディングされた注文テーブルがあり、クエリではそのうちのいずれか一方のみが指定されることがあります。

ルーティング動作:RANGE_HASH(COL1, COL2, N) は、N 文字分の COL1 の末尾文字を取得し、ハッシュ値を計算します。COL1 が存在しない場合は、COL2 にフォールバックします。両方のカラムは、文字または数値型である必要があります。

制約事項:

  • テーブル作成後に、2 つのシャードキーを変更することはできません。

  • 特定の行において、2 つのシャードキーが異なるシャードにハッシュされる場合、挿入は失敗します。

CREATE TABLE test_order_tb (
  id bigint not null auto_increment,
  seller_id varchar(30) DEFAULT NULL,
  order_id varchar(30) DEFAULT NULL,
  buyer_id varchar(30) DEFAULT NULL,
  create_time datetime DEFAULT NULL,
  primary key(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
  DBPARTITION BY RANGE_HASH(buyer_id, order_id, 10)
  TBPARTITION BY RANGE_HASH(buyer_id, order_id, 10) TBPARTITIONS 3;

日付ベースのシャーディング

クエリがほぼ常に特定の期間に限定される時系列データに対して、日付関数を使用します。各関数は、日付カラムをカレンダー単位に基づいて物理テーブルにマップするため、日付カラムを指定したクエリは関連するシャードのみにヒットします。

WEEK — 曜日ごとにシャーディング (データベースシャードあたり 7 個のテーブル)

WEEK(actionDate)DAY_OF_WEEK 値 (1–7) を返します。たとえば、2017-02-27 (月曜日) は 2 を返すため、該当行は user_log_2 に配置されます。2017-02-26 (日曜日) は 1 を返すため、該当行は user_log_1 に配置されます。

CREATE TABLE user_log(
  userId int,
  name varchar(30),
  operation varchar(30),
  actionDate DATE
) DBPARTITION BY hash(userId) TBPARTITION BY WEEK(actionDate) TBPARTITIONS 7;

トポロジーを確認します。データベースシャードあたり 7 個のテーブルシャードが存在し、それぞれが平日の 1 日に対応しています。

SHOW TOPOLOGY FROM user_log;
+------+------------------------------------------------------------------+------------+
| ID   | GROUP_NAME                                                       | TABLE_NAME |
+------+------------------------------------------------------------------+------------+
|    0 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0000_RDS | user_log_0 |
|    1 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0000_RDS | user_log_1 |
|    2 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0000_RDS | user_log_2 |
|    3 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0000_RDS | user_log_3 |
|    4 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0000_RDS | user_log_4 |
|    5 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0000_RDS | user_log_5 |
|    6 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0000_RDS | user_log_6 |
|    7 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0001_RDS | user_log_0 |
|    8 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0001_RDS | user_log_1 |
|    9 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0001_RDS | user_log_2 |
|   10 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0001_RDS | user_log_3 |
|   11 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0001_RDS | user_log_4 |
|   12 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0001_RDS | user_log_5 |
|   13 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0001_RDS | user_log_6 |
...
|   49 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log_0 |
|   50 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log_1 |
|   51 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log_2 |
|   52 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log_3 |
|   53 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log_4 |
|   54 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log_5 |
|   55 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log_6 |
+------+------------------------------------------------------------------+------------+
56 rows in set (0.01 sec)
出力が長いため、一部の行は省略記号 (...) で省略されています。

シャーディングルールを確認します。

SHOW RULE FROM user_log;
+------+------------+-----------+------------------+---------------------+--------------------+------------------+---------------------+--------------------+
| ID   | TABLE_NAME | BROADCAST | DB_PARTITION_KEY | DB_PARTITION_POLICY | DB_PARTITION_COUNT | TB_PARTITION_KEY | TB_PARTITION_POLICY | TB_PARTITION_COUNT |
+------+------------+-----------+------------------+---------------------+--------------------+------------------+---------------------+--------------------+
|    0 | user_log   |         0 | userId           | hash                | 8                  | actionDate       | week                | 7                  |
+------+------------+-----------+------------------+---------------------+--------------------+------------------+---------------------+--------------------+
1 row in set (0.00 sec)

データベースシャードキーおよびテーブルシャードキーの両方が定義されている場合、両方のカラムを指定したクエリは、対応する物理テーブルに直接ルーティングされます。

MM — 年間の月ごとにシャーディング (データベースシャードあたり 12 個のテーブル)

MM(actionDate)MONTH_OF_YEAR 値 (01–12) を返します。たとえば、2017-02-27 は 02 を返すため、該当行は user_log2_02 に配置されます。2016-12-27 は 12 を返しますが、12 % 12 = 0 のため、該当行は user_log2_00 に配置されます。

CREATE TABLE user_log2(
  userId int,
  name varchar(30),
  operation varchar(30),
  actionDate DATE
) DBPARTITION BY hash(userId) TBPARTITION BY MM(actionDate) TBPARTITIONS 12;

トポロジーを確認します。データベースシャードあたり 12 個のテーブルシャードが存在します。

SHOW TOPOLOGY FROM user_log2;
+------+------------------------------------------------------------------+--------------+
| ID   | GROUP_NAME                                                       | TABLE_NAME   |
+------+------------------------------------------------------------------+--------------+
|    0 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0000_RDS | user_log2_00 |
|    1 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0000_RDS | user_log2_01 |
|    2 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0000_RDS | user_log2_02 |
|    3 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0000_RDS | user_log2_03 |
|    4 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0000_RDS | user_log2_04 |
|    5 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0000_RDS | user_log2_05 |
|    6 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0000_RDS | user_log2_06 |
|    7 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0000_RDS | user_log2_07 |
|    8 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0000_RDS | user_log2_08 |
|    9 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0000_RDS | user_log2_09 |
|   10 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0000_RDS | user_log2_10 |
|   11 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0000_RDS | user_log2_11 |
|   12 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0001_RDS | user_log2_00 |
|   13 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0001_RDS | user_log2_01 |
|   14 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0001_RDS | user_log2_02 |
|   15 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0001_RDS | user_log2_03 |
|   16 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0001_RDS | user_log2_04 |
|   17 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0001_RDS | user_log2_05 |
|   18 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0001_RDS | user_log2_06 |
|   19 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0001_RDS | user_log2_07 |
|   20 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0001_RDS | user_log2_08 |
|   21 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0001_RDS | user_log2_09 |
|   22 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0001_RDS | user_log2_10 |
|   23 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0001_RDS | user_log2_11 |
...
|   84 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log2_00 |
|   85 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log2_01 |
|   86 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log2_02 |
|   87 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log2_03 |
|   88 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log2_04 |
|   89 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log2_05 |
|   90 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log2_06 |
|   91 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log2_07 |
|   92 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log2_08 |
|   93 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log2_09 |
|   94 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log2_10 |
|   95 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log2_11 |
+------+------------------------------------------------------------------+--------------+
96 rows in set (0.02 sec)
出力が長いため、一部の行は省略記号 (...) で省略されています。

シャーディングルールを確認します。

SHOW RULE FROM user_log2;
+------+------------+-----------+------------------+---------------------+--------------------+------------------+---------------------+--------------------+
| ID   | TABLE_NAME | BROADCAST | DB_PARTITION_KEY | DB_PARTITION_POLICY | DB_PARTITION_COUNT | TB_PARTITION_KEY | TB_PARTITION_POLICY | TB_PARTITION_COUNT |
+------+------------+-----------+------------------+---------------------+--------------------+------------------+---------------------+--------------------+
|    0 | user_log2  |         0 | userId           | hash                | 8                  | actionDate       | mm                  | 12                 |
+------+------------+-----------+------------------+---------------------+--------------------+------------------+---------------------+--------------------+
1 row in set (0.00 sec)

DD — 月間の日ごとにシャーディング (データベースシャードあたり 31 個のテーブル)

DD(actionDate)DAY_OF_MONTH 値 (1–31) を返します。たとえば、2017-02-27 は 27 を返すため、該当行は user_log_27 に配置されます。

CREATE TABLE user_log3(
  userId int,
  name varchar(30),
  operation varchar(30),
  actionDate DATE
) DBPARTITION BY hash(userId) TBPARTITION BY DD(actionDate) TBPARTITIONS 31;

トポロジーを確認します。データベースシャードあたり 31 個のテーブルシャードが存在します。

SHOW TOPOLOGY FROM user_log3;
+------+------------------------------------------------------------------+--------------+
| ID   | GROUP_NAME                                                       | TABLE_NAME   |
+------+------------------------------------------------------------------+--------------+
|    0 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0000_RDS | user_log3_00 |
|    1 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0000_RDS | user_log3_01 |
|    2 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0000_RDS | user_log3_02 |
...
|   30 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0000_RDS | user_log3_30 |
...
|  237 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log3_20 |
|  238 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log3_21 |
|  239 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log3_22 |
|  240 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log3_23 |
|  241 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log3_24 |
|  242 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log3_25 |
|  243 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log3_26 |
|  244 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log3_27 |
|  245 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log3_28 |
|  246 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log3_29 |
|  247 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log3_30 |
+------+------------------------------------------------------------------+--------------+
248 rows in set (0.01 sec)
出力が長いため、一部の行は省略記号 (...) で省略されています。

シャーディングルールを確認します。

SHOW RULE FROM user_log3;
+------+------------+-----------+------------------+---------------------+--------------------+------------------+---------------------+--------------------+
| ID   | TABLE_NAME | BROADCAST | DB_PARTITION_KEY | DB_PARTITION_POLICY | DB_PARTITION_COUNT | TB_PARTITION_KEY | TB_PARTITION_POLICY | TB_PARTITION_COUNT |
+------+------------+-----------+------------------+---------------------+--------------------+------------------+---------------------+--------------------+
|    0 | user_log3  |         0 | userId           | hash                | 8                  | actionDate       | dd                  | 31                 |
+------+------------+-----------+------------------+---------------------+--------------------+------------------+---------------------+--------------------+
1 row in set (0.01 sec)

MMDD — 年間の日ごとにシャーディング (データベースシャードあたり最大 365 個のテーブル)

MMDD(actionDate)DAY_OF_YEAR % 365 を計算します。たとえば、2017-02-27 は 58 を返すため、該当行は user_log_58 に配置されます。TBPARTITIONS 365 を指定すると、粒度が最大になります。あるいは、総テーブル数を減らすために、より小さい値を指定することもできます。

365 パーティション (1 年間の各日に 1 つ) を使用した例:

CREATE TABLE user_log4(
  userId int,
  name varchar(30),
  operation varchar(30),
  actionDate DATE
) DBPARTITION BY hash(userId) TBPARTITION BY MMDD(actionDate) TBPARTITIONS 365;

トポロジーを確認します。データベースシャードあたり 365 個のテーブルシャード、合計で 2,920 個のテーブルが存在します。

SHOW TOPOLOGY FROM user_log4;
+------+------------------------------------------------------------------+---------------+
| ID   | GROUP_NAME                                                       | TABLE_NAME    |
+------+------------------------------------------------------------------+---------------+
...
| 2896 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log4_341 |
| 2897 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log4_342 |
| 2898 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log4_343 |
| 2899 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log4_344 |
| 2900 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log4_345 |
| 2901 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log4_346 |
| 2902 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log4_347 |
| 2903 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log4_348 |
| 2904 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log4_349 |
| 2905 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log4_350 |
| 2906 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log4_351 |
| 2907 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log4_352 |
| 2908 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log4_353 |
| 2909 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log4_354 |
| 2910 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log4_355 |
| 2911 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log4_356 |
| 2912 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log4_357 |
| 2913 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log4_358 |
| 2914 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log4_359 |
| 2915 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log4_360 |
| 2916 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log4_361 |
| 2917 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log4_362 |
| 2918 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log4_363 |
| 2919 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log4_364 |
+------+------------------------------------------------------------------+---------------+
2920 rows in set (0.07 sec)
出力が長いため、一部の行は省略記号 (...) で省略されています。

シャーディングルールを確認します。

SHOW RULE FROM user_log4;
+------+------------+-----------+------------------+---------------------+--------------------+------------------+---------------------+--------------------+
| ID   | TABLE_NAME | BROADCAST | DB_PARTITION_KEY | DB_PARTITION_POLICY | DB_PARTITION_COUNT | TB_PARTITION_KEY | TB_PARTITION_POLICY | TB_PARTITION_COUNT |
+------+------------+-----------+------------------+---------------------+--------------------+------------------+---------------------+--------------------+
|    0 | user_log4  |         0 | userId           | hash                | 8                  | actionDate       | mmdd                | 365                |
+------+------------+-----------+------------------+---------------------+--------------------+------------------+---------------------+--------------------+
1 row in set (0.02 sec)

10 パーティション (365 日をモジュロ演算で 10 個のバケットに割り当てる) を使用した例:

CREATE TABLE user_log5(
  userId int,
  name varchar(30),
  operation varchar(30),
  actionDate DATE
) DBPARTITION BY hash(userId) TBPARTITION BY MMDD(actionDate) TBPARTITIONS 10;

トポロジーを確認します。データベースシャードあたり 10 個のテーブルシャード、合計で 80 個のテーブルが存在します。

SHOW TOPOLOGY FROM user_log5;
+------+------------------------------------------------------------------+--------------+
| ID   | GROUP_NAME                                                       | TABLE_NAME   |
+------+------------------------------------------------------------------+--------------+
|    0 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0000_RDS | user_log5_00 |
|    1 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0000_RDS | user_log5_01 |
|    2 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0000_RDS | user_log5_02 |
|    3 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0000_RDS | user_log5_03 |
|    4 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0000_RDS | user_log5_04 |
|    5 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0000_RDS | user_log5_05 |
|    6 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0000_RDS | user_log5_06 |
|    7 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0000_RDS | user_log5_07 |
|    8 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0000_RDS | user_log5_08 |
|    9 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0000_RDS | user_log5_09 |
...
|   70 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log5_00 |
|   71 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log5_01 |
|   72 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log5_02 |
|   73 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log5_03 |
|   74 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log5_04 |
|   75 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log5_05 |
|   76 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log5_06 |
|   77 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log5_07 |
|   78 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log5_08 |
|   79 | SANGUAN_TEST_123_1488766060743ACTJSANGUAN_TEST_123_WVVP_0007_RDS | user_log5_09 |
+------+------------------------------------------------------------------+--------------+
80 rows in set (0.02 sec)
出力が長いため、一部の行は省略記号 (...) で省略されています。

シャーディングルールを確認します。

SHOW RULE FROM user_log5;
+------+------------+-----------+------------------+---------------------+--------------------+------------------+---------------------+--------------------+
| ID   | TABLE_NAME | BROADCAST | DB_PARTITION_KEY | DB_PARTITION_POLICY | DB_PARTITION_COUNT | TB_PARTITION_KEY | TB_PARTITION_POLICY | TB_PARTITION_COUNT |
+------+------------+-----------+------------------+---------------------+--------------------+------------------+---------------------+--------------------+
|    0 | user_log5  |         0 | userId           | hash                | 8                  | actionDate       | mmdd                | 10                 |
+------+------------+-----------+------------------+---------------------+--------------------+------------------+---------------------+--------------------+
1 row in set (0.01 sec)

GSI の定義

グローバルセカンダリインデックス (GSI) は、ベーステーブルとは異なるキーでシャーディングされた別個のインデックステーブルを維持することで、シャードキー以外のカラムに対する効率的なクエリを可能にします。これにより、全シャードにわたるスキャッター・ギャザー・スキャンを回避できます。以下の例では、8 つのデータベースシャードを想定しています。

非一意 GSI の定義

次の例では、t_orderorder_id でシャーディングし、g_i_seller という seller_id でシャーディングされた GSI を作成します。これにより、seller_id をフィルター条件とするクエリが、全シャードにわたるフルスキャンを回避できます。

CREATE TABLE t_order (
  `id` bigint(11) NOT NULL AUTO_INCREMENT,
  `order_id` varchar(20) DEFAULT NULL,
  `buyer_id` varchar(20) DEFAULT NULL,
  `seller_id` varchar(20) DEFAULT NULL,
  `order_snapshot` longtext DEFAULT NULL,
  `order_detail` longtext DEFAULT NULL,
  PRIMARY KEY (`id`),
  GLOBAL INDEX `g_i_seller`(`seller_id`) DBPARTITION BY hash(`seller_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 DBPARTITION BY hash(`order_id`);
  • t_order は、order_id でシャーディングされたベーステーブルです。

  • g_i_seller は、seller_id でシャーディングされたインデックステーブルです。デフォルト以外のカバリング列は指定されていません。

  • GLOBAL INDEX g_i_seller(seller_id) DBPARTITION BY hash(seller_id) という句で GSI を定義しています。

インデックスを確認します。デフォルトのカバリング列には、プライマリキー (id) およびベーステーブルのシャードキー (order_id) が含まれます。

SHOW INDEX FROM t_order;
+---------+------------+-------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+----------+---------------+
| TABLE   | NON_UNIQUE | KEY_NAME                | SEQ_IN_INDEX | COLUMN_NAME | COLLATION | CARDINALITY | SUB_PART | PACKED | NULL | INDEX_TYPE | COMMENT  | INDEX_COMMENT |
+---------+------------+-------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+----------+---------------+
| t_order |          0 | PRIMARY                 |            1 | id          | A         |           0 |     NULL | NULL   |      | BTREE      |          |               |
| t_order |          1 | auto_shard_key_order_id |            1 | order_id    | A         |           0 |     NULL | NULL   | YES  | BTREE      |          |               |
| t_order |          1 | g_i_seller              |            1 | seller_id   | NULL      |           0 |     NULL | NULL   | YES  | BTREE      |          |               |
| t_order |          1 | g_i_seller              |            2 | id          | NULL      |           0 |     NULL | NULL   |      | GLOBAL     | COVERING |               |
| t_order |          1 | g_i_seller              |            3 | order_id    | NULL      |           0 |     NULL | NULL   | YES  | GLOBAL     | COVERING |               |
+---------+------------+-------------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+----------+---------------+

SHOW GLOBAL INDEX を使用して GSI のメタデータを照会します。

SHOW GLOBAL INDEX FROM t_order;
+--------+---------+------------+------------+-------------+----------------+------------+------------------+---------------------+--------------------+------------------+---------------------+--------------------+--------+
| SCHEMA | TABLE   | NON_UNIQUE | KEY_NAME   | INDEX_NAMES | COVERING_NAMES | INDEX_TYPE | DB_PARTITION_KEY | DB_PARTITION_POLICY | DB_PARTITION_COUNT | TB_PARTITION_KEY | TB_PARTITION_POLICY | TB_PARTITION_COUNT | STATUS |
+--------+---------+------------+------------+-------------+----------------+------------+------------------+---------------------+--------------------+------------------+---------------------+--------------------+--------+
| d7     | t_order | 1          | g_i_seller | seller_id   | id, order_id   | NULL       | seller_id        | HASH                 | 8                  |                  | NULL                | NULL               | PUBLIC |
+--------+---------+------------+------------+-------------+----------------+------------+------------------+---------------------+--------------------+------------------+---------------------+--------------------+--------+

インデックステーブルのスキーマを確認します。インデックステーブルには、プライマリキー、シャードキー、およびデフォルトのカバリング列が含まれます。プライマリキー列には AUTO_INCREMENT 属性は設定されず、ベーステーブルにはローカルインデックスがありません。

SHOW CREATE TABLE g_i_seller;
+------------+-----------------------------------------------------------+
| Table      | Create Table                                              |
+------------+-----------------------------------------------------------+
| g_i_seller | CREATE TABLE `g_i_seller` (
  `id` bigint(11) NOT NULL,
  `order_id` varchar(20) DEFAULT NULL,
  `seller_id` varchar(20) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `auto_shard_key_seller_id` (`seller_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 DBPARTITION BY hash(`seller_id`) |
+------------+-----------------------------------------------------------+

一意 GSI の定義

一意 GSI は、インデックス化されたカラムの一意性をすべてのデータベースシャード全体で保証します。次の例では、g_i_buyer という buyer_id 上の一意 GSI を追加し、seller_id および order_snapshot を明示的なカバリング列として指定しています。

CREATE TABLE t_order (
  `id` bigint(11) NOT NULL AUTO_INCREMENT,
  `order_id` varchar(20) DEFAULT NULL,
  `buyer_id` varchar(20) DEFAULT NULL,
  `seller_id` varchar(20) DEFAULT NULL,
  `order_snapshot` longtext DEFAULT NULL,
  `order_detail` longtext DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE GLOBAL INDEX `g_i_buyer`(`buyer_id`) COVERING(`seller_id`, `order_snapshot`)
    DBPARTITION BY hash(`buyer_id`) TBPARTITION BY hash(`buyer_id`) TBPARTITIONS 3
) ENGINE=InnoDB DEFAULT CHARSET=utf8 DBPARTITION BY hash(`order_id`);
  • t_order は、order_id でシャーディングされたベーステーブルです。

  • g_i_buyer は、buyer_id でシャーディングされたインデックステーブルであり、各データベースシャードに 3 つの物理テーブルが存在します。カバリング列には、デフォルトの列に加えて seller_id および order_snapshot が含まれます。

  • UNIQUE GLOBAL INDEX g_i_buyer(buyer_id) COVERING(seller_id, order_snapshot) DBPARTITION BY hash(buyer_id) TBPARTITION BY hash(buyer_id) TBPARTITIONS 3 という句で一意 GSI を定義しています。

インデックスを確認します。デフォルトのカバリング列 (id, order_id) および明示的に指定されたカバリング列 (seller_id, order_snapshot) がすべて存在します。

SHOW INDEX FROM t_order;
+--------------+------------+-------------------------+--------------+----------------+-----------+-------------+----------+--------+------+------------+----------+---------------+
| TABLE        | NON_UNIQUE | KEY_NAME                | SEQ_IN_INDEX | COLUMN_NAME    | COLLATION | CARDINALITY | SUB_PART | PACKED | NULL | INDEX_TYPE | COMMENT  | INDEX_COMMENT |
+--------------+------------+-------------------------+--------------+----------------+-----------+-------------+----------+--------+------+------------+----------+---------------+
| t_order_dthb |          0 | PRIMARY                 |            1 | id             | A         |           0 |     NULL | NULL   |      | BTREE      |          |               |
| t_order_dthb |          1 | auto_shard_key_order_id |            1 | order_id       | A         |           0 |     NULL | NULL   | YES  | BTREE      |          |               |
| t_order      |          0 | g_i_buyer               |            1 | buyer_id       | NULL      |           0 |     NULL | NULL   | YES  | GLOBAL     | INDEX    |               |
| t_order      |          1 | g_i_buyer               |            2 | id             | NULL      |           0 |     NULL | NULL   |      | GLOBAL     | COVERING |               |
| t_order      |          1 | g_i_buyer               |            3 | order_id       | NULL      |           0 |     NULL | NULL   | YES  | GLOBAL     | COVERING |               |
| t_order      |          1 | g_i_buyer               |            4 | seller_id      | NULL      |           0 |     NULL | NULL   | YES  | GLOBAL     | COVERING |               |
| t_order      |          1 | g_i_buyer               |            5 | order_snapshot | NULL      |           0 |     NULL | NULL   | YES  | GLOBAL     | COVERING |               |
+--------------+------------+-------------------------+--------------+----------------+-----------+-------------+----------+--------+------+------------+----------+---------------+

GSI のメタデータを照会します。

SHOW GLOBAL INDEX FROM t_order;
+--------+---------+------------+-----------+-------------+-----------------------------------------+------------+------------------+---------------------+--------------------+------------------+---------------------+--------------------+--------+
| SCHEMA | TABLE   | NON_UNIQUE | KEY_NAME  | INDEX_NAMES | COVERING_NAMES                          | INDEX_TYPE | DB_PARTITION_KEY | DB_PARTITION_POLICY | DB_PARTITION_COUNT | TB_PARTITION_KEY | TB_PARTITION_POLICY | TB_PARTITION_COUNT | STATUS |
+--------+---------+------------+-----------+-------------+-----------------------------------------+------------+------------------+---------------------+--------------------+------------------+---------------------+--------------------+--------+
| d7     | t_order | 0          | g_i_buyer | buyer_id    | id, order_id, seller_id, order_snapshot | NULL       | buyer_id         | HASH                | 8                  | buyer_id         | HASH                | 3                  | PUBLIC |
+--------+---------+------------+-----------+-------------+-----------------------------------------+------------+------------------+---------------------+--------------------+------------------+---------------------+--------------------+--------+

インデックステーブルのスキーマを確認します。一意 GSI を確実に保証するために、デフォルトでテーブルが作成されます。プライマリキー列には AUTO_INCREMENT 属性は設定されません。

SHOW CREATE TABLE g_i_buyer;
+-----------+--------------------------------------------------------------------------------------------------------+
| Table     | Create Table                                                                                           |
+-----------+--------------------------------------------------------------------------------------------------------+
| g_i_buyer | CREATE TABLE `g_i_buyer` (
  `id` bigint(11) NOT NULL,
  `order_id` varchar(20) DEFAULT NULL,
  `buyer_id` varchar(20) DEFAULT NULL,
  `seller_id` varchar(20) DEFAULT NULL,
  `order_snapshot` longtext,
  PRIMARY KEY (`id`),
  UNIQUE KEY `auto_shard_key_buyer_id` (`buyer_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 DBPARTITION BY hash(`buyer_id`) TBPARTITION BY hash(`buyer_id`) TBPARTITIONS 3 |
+-----------+--------------------------------------------------------------------------------------------------------+

次のステップ