このトピックでは、PolarDB-X の AUTO モードデータベースでパーティションテーブルを作成するための DDL 構文、句、およびパラメーターについて説明します。
注意事項
-
パーティションテーブルを作成する構文を使用する前に、現在の論理データベースが自動パーティションモード (
mode='auto') であることを確認してください。この構文は他のモードではサポートされていません。現在の論理データベースのモードを確認するには、SHOW CREATE DATABASE db_nameコマンドを実行します。例:CREATE DATABASE part_db mode='auto'; Query OK, 1 row affected (4.29 sec) SHOW CREATE DATABASE part_db; +----------+-----------------------------------------------+ | DATABASE | CREATE DATABASE | +----------+-----------------------------------------------+ | part_db | CREATE DATABASE `part_db` /* MODE = 'auto' */ | +----------+-----------------------------------------------+ 1 row in set (0.18 sec)CREATE DATABASE構文の詳細については、「CREATE DATABASE」をご参照ください。 -
パーティションテーブルのプライマリキーにパーティションキーが含まれておらず、自動インクリメント主キーでもない場合は、アプリケーションレベルでプライマリキーが一意であることを保証する必要があります。
-
サブパーティショニング機能を使用するには、インスタンスのバージョンが 5.4.17-16952556 以降である必要があります。
構文
CREATE [PARTITION] TABLE [IF NOT EXISTS] tbl_name
(create_definition, ...)
[table_options]
[table_partition_definition]
[local_partition_definition]
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] ...
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}
# グローバルセカンダリインデックスのオプション
global_secondary_index_option:
[COVERING (col_name,...)]
[partition_options]
[VISIBLE|INVISIBLE]
table_options:
table_option [[,] table_option] ...
table_option: {
# テーブルグループを指定
TABLEGROUP [=] value,...,}
# パーティションテーブルの型定義
table_partition_definition:
single
| broadcast
| partition_options
# パーティション定義
partition_options:
partition_columns_definition
[subpartition_columns_definition]
[subpartition_specs_definition] /* テンプレート化されたサブパーティションを定義します。 */
partition_specs_definition
# パーティションキー定義
partition_columns_definition:
PARTITION BY
HASH({column_name | partition_func(column_name)}) partitions_count
| KEY(column_list) partitions_count
| RANGE ({column_name | partition_func(column_name)})
| RANGE COLUMNS(column_list)
| LIST ({column_name | partition_func(column_name)})
| LIST COLUMNS(column_list)
| CO_HASH({column_expr_list}) partitions_count
# サブパーティションキー定義
subpartition_columns_definition:
SUBPARTITION BY
HASH({column_name | partition_func(column_name)}) subpartitions_count
| KEY(column_list) subpartitions_count
| RANGE ({column_name | partition_func(column_name)})
| RANGE COLUMNS(column_list)
| LIST ({column_name | partition_func(column_name)})
| LIST COLUMNS(column_list)
| CO_HASH({column_expr_list}) partitions_count
column_expr_list:
{column_name | partition_func(column_name)},{column_name | partition_func(column_name)}[,{column_name | partition_func(column_name)},...]
partitions_count:
PARTITIONS partition_count
subpartitions_count:
SUBPARTITIONS partition_count
# パーティション関数
partition_func:
YEAR
| TO_DAYS
| TO_MONTHS
| TO_WEEKS
| TO_SECOND
| UNIX_TIMESTAMP
| MONTH
| DAYOFWEEK
| DAYOFMONTH
| DAYOFYEAR
| SUBSTR
| SUBSTRING
| RIGHT
| LEFT
# パーティション仕様
partition_specs_definition:
hash_partition_list
| range_partition_list
| list_partition_list
# サブパーティション仕様
subpartition_specs_definition:
hash_subpartition_list
| range_subpartition_list
| list_subpartition_list
# HASH/KEY パーティション定義
hash_partition_list:
/* HASH パーティショニングの場合、個々のパーティション定義はオプションです。 */
| ( hash_partition [, hash_partition, ...] )
hash_partition:
PARTITION partition_name [partition_spec_options] /* サブパーティションがない、またはテンプレート化されたサブパーティションを使用するパーティションテーブルの場合。 */
| PARTITION partition_name subpartitions_count [subpartition_specs_definition] /* パーティション内で非テンプレート化されたサブパーティションを定義します。 */
# HASH/KEY サブパーティション定義
hash_subpartition_list:
| empty
| ( hash_subpartition [, hash_subpartition, ...] )
hash_subpartition:
SUBPARTITION subpartition_name [partition_spec_options]
# RANGE/RANGE COLUMNS パーティション定義
range_partition_list:
( range_partition [, range_partition, ... ] )
range_partition:
PARTITION partition_name VALUES LESS THAN (range_bound_value) [partition_spec_options] /* サブパーティションがない、またはテンプレート化されたサブパーティションを使用するパーティションテーブルの場合。 */
| PARTITION partition_name VALUES LESS THAN (range_bound_value) [[subpartitions_count] [subpartition_specs_definition]] /* パーティション内で非テンプレート化されたサブパーティションを定義します。 */
# RANGE/RANGE COLUMNS サブパーティション定義
range_subpartition_list:
( range_subpartition [, range_subpartition, ... ] )
range_subpartition:
SUBPARTITION subpartition_name VALUES LESS THAN (range_bound_value) [partition_spec_options]
range_bound_value:
maxvalue /* RANGE パーティショニングの MAXVALUE パーティションを定義します。 */
| expr /* 単一パーティションキーの境界値 */
| value_list /* 複数パーティションキーの境界値 */
# LIST/LIST COLUMNS パーティション定義
list_partition_list:
(list_partition [, list_partition ...])
list_partition:
PARTITION partition_name VALUES IN (list_bound_value) [partition_spec_options] /* サブパーティションがない、またはテンプレート化されたサブパーティションを使用するパーティションテーブルの場合。 */
| PARTITION partition_name VALUES IN (list_bound_value) [[subpartitions_count] [subpartition_specs_definition]] /* パーティション内で非テンプレート化されたサブパーティションを定義します。 */
# LIST/LIST COLUMNS サブパーティション定義
list_subpartition_list:
(list_subpartition [, list_subpartition ...])
list_subpartition:
SUBPARTITION subpartition_name VALUES IN (list_bound_value) [partition_spec_options]
list_bound_value:
default /* LIST パーティショニングの DEFAULT パーティションを定義します。 */
| value_set
value_set:
value_list /* 単一パーティションキーの値のセット */
| (value_list) [, (value_list), ...] /* 複数パーティションキーの値のセット */
value_list:
value [, value, ...]
partition_spec_options:
[[STORAGE] ENGINE [=] engine_name]
[COMMENT [=] 'string']
[LOCALITY [=] locality_option]
table_option:
[[STORAGE] ENGINE [=] engine_name]
[COMMENT [=] 'string']
[{CHARSET | CHARACTER SET} [=] charset]
[COLLATE [=] collation]
[TABLEGROUP [=] table_group_id]
[LOCALITY [=] locality_option]
locality_option:
'dn=storage_inst_id_list'
storage_inst_id_list:
storage_inst_id[,storage_inst_id_list]
local_partition_definition:
LOCAL PARTITION BY RANGE (column_name)
[STARTWITH 'yyyy-MM-dd']
INTERVAL interval_count [YEAR|MONTH|DAY]
[EXPIRE AFTER expire_after_count]
[PRE ALLOCATE pre_allocate_count]
[PIVOTDATE pivotdate_func]
[DISABLE SCHEDULE]
pivotdate_func:
NOW()
| DATE_ADD(...)
| DATE_SUB(...)
PolarDB-X の DDL 構文は MySQL に基づいています。上記の構文は主な違いをハイライトしています。完全な構文については、MySQL ドキュメントをご参照ください。
用語集
-
パーティションキー:水平パーティショニングに使用されるパーティションテーブル内の 1 つ以上の列。
-
パーティション列:水平パーティション化されたテーブルでパーティションルーティングと計算に使用される列。通常、パーティションキーの一部です。
-
ベクターパーティションキー:1 つ以上のパーティション列で構成されるパーティションキー。
-
単一列パーティションキー:単一のパーティション列で構成されるパーティションキー。
-
プレフィックスパーティション列:N (N > 1) 個のパーティション列を持つベクターパーティションキーの場合、そのプレフィックスは最初の K 列で構成されます (1 <= K < N)。
-
パーティション関数:パーティション列を入力として受け入れる関数。その出力はルーティング計算の値を提供します。
-
パーティションプルーニング:パーティション定義とクエリ条件に基づいて不要なパーティションのスキャンを回避するクエリ最適化技術。
-
ホットスポット分割:後続のパーティション列を使用してホットパーティションを分割する負荷分散技術。この分割は、ベクターパーティションキーのプレフィックスパーティション列でアクセスホットスポットや不均一なデータ分布が発生した場合にトリガーされます。
-
物理パーティション:DN ノード上の物理サブテーブルと 1 対 1 でマッピングされるパーティション。
-
論理パーティション:1 つ以上の物理パーティションにマッピングされる仮想パーティション。たとえば、サブパーティショニングで作成されたテーブルでは、第 1 レベルのパーティションは論理パーティションです。
パラメーター
|
パラメーター |
説明 |
|
|
テーブル内の列のデフォルトの文字セットを指定します。以下の文字セットがサポートされています:
|
|
|
テーブル内の列のデフォルトの照合順序を指定します。以下の照合順序がサポートされています:
|
|
|
パーティションテーブルのテーブルグループを指定します。省略した場合、システムはテーブルのパーティショニングメソッドに一致する互換性のあるテーブルグループを自動的に検索または作成します。 |
|
|
パーティションテーブルを格納するデータノードを指定します。 |
単一テーブル
PolarDB-X では、SINGLE キーワードを使用して非パーティション化テーブルを作成できます。例:
CREATE TABLE single_tbl(
id bigint not null auto_increment,
bid int,
name varchar(30),
primary key(id)
) SINGLE;
ブロードキャストテーブル
PolarDB-X では、BROADCAST キーワードを指定してブロードキャストテーブルを作成できます。ブロードキャストテーブルは、すべてのデータノードにデータの同一コピーを保持します。例:
CREATE TABLE broadcast_tbl(
id bigint not null auto_increment,
bid int,
name varchar(30),
primary key(id)
) BROADCAST;
パーティションテーブル
パーティションタイプ
PolarDB-X では、パーティション句を指定することで、ビジネス要件に合わせてパーティションテーブルを作成できます。PolarDB-X は、以下の 4 種類のパーティショニングをサポートしています:
-
ハッシュパーティショニング:この戦略は、パーティション列の値またはパーティション関数式に組み込みの一貫性ハッシュアルゴリズムを適用してデータをルーティングします。ハッシュパーティショニングは、パーティション関数式または複数のパーティション列をパーティションキーとして使用できるかどうかに応じて、KEY パーティショニングとハッシュパーティショニングの 2 つの戦略に細分化されます。
-
RANGE パーティショニング:この戦略は、パーティション列の値またはパーティション関数式を事前定義されたパーティション範囲と比較してデータをルーティングします。RANGE パーティショニングは、パーティション関数式または複数のパーティション列をパーティションキーとして使用できるかどうかに応じて、RANGE COLUMNS パーティショニングとRANGE パーティショニングの 2 つの戦略に細分化されます。
-
LIST パーティショニング:RANGE パーティショニングと同様に、この戦略は、パーティション列の値またはパーティション関数式がパーティションの事前定義された値のリストに含まれているかどうかを確認してデータをルーティングします。LIST パーティショニングは、複数のパーティション列をパーティションキーとして使用するかどうか、およびその方法に基づいて、LIST COLUMNS パーティショニングとLIST パーティショニングの 2 つの戦略に細分化されます。
-
CoHash:これは、PolarDB-X の拡張ハッシュパーティショニング戦略であり、特定の一般的なアプリケーションシナリオ向けに設計されています。この戦略により、複数の相関するパーティション列に基づいてテーブルを水平にパーティショニングできます。
ハッシュタイプ
PolarDB-X には、ハッシュベースのパーティショニングにはハッシュパーティショニングと KEY パーティショニングの 2 種類があります。どちらもネイティブ MySQL の標準パーティショニング構文の一部です。パーティション分割、マージ、移行などの柔軟なパーティション管理機能や、ベクターパーティションキーのホットスポット分割をサポートするために、PolarDB-X はハッシュおよび KEY パーティショニングのルーティングを再定義しています。これは MySQL の CREATE TABLE 構文と構文的に互換性がありますが、その基盤となる パーティションルーティング の実装は MySQL とは異なります。次の表は、KEY パーティショニングとハッシュパーティショニングの違いを説明しています:
表 1. KEY パーティショニング戦略とハッシュパーティショニング戦略の比較
|
パーティショニング戦略 |
パーティションキーのサポート |
パーティション関数のサポート |
構文例 |
特徴と制限事項 |
ルーティング (ポイントクエリ) |
|
Key (デフォルトのパーティショニング戦略) |
単一列パーティションキー |
いいえ |
PARTITION BY KEY(c1) |
|
|
|
ベクターパーティションキー |
いいえ |
PARTITION BY KEY(c1, c2, ..., cn) |
|
|
|
|
Hash |
単一列パーティションキー |
いいえ |
PARTITION BY HASH(c1) |
|
|
|
はい |
PARTITION BY HASH(YEAR(c1)) |
|
|||
|
ベクターパーティションキー |
いいえ |
PARTITION BY HASH(c1, c2, ..., cn) |
|
|
例 1-1:KEY パーティション
KEY パーティショニングは、PolarDB-X のデフォルトのパーティショニングメソッドでもあります。このメソッドはベクターパーティションキーをサポートします。たとえば、次のステートメントは、ユーザー名 (name) とユーザー ID (id) で 8 つのパーティションに分割されたテーブルを作成します:
CREATE TABLE key_tbl(
id bigint not null auto_increment,
bid int,
name varchar(30),
birthday datetime not null,
primary key(id)
)
PARTITION BY KEY(name, id)
PARTITIONS 8;
ベクターパーティションキーを持つ KEY パーティションを使用するパーティションテーブルの場合、ルーティングはデフォルトで最初のパーティション列 (name) にのみ依存します。したがって、WHERE 句にこの最初のパーティション列の等価条件が含まれている場合、パーティションプルーニングがトリガーされます。例:
## このクエリはパーティションプルーニングをトリガーし、単一のパーティションのみをスキャンします。
SELECT id from key_tbl where name='Jack';
最初のパーティション列である name がデータ不均衡やデータホットスポットを引き起こす場合、次のパーティション列である id などを使用してパーティション分割を実行できます。詳細については、「テーブルグループレベルのパーティションの変更 (AUTO モード)」をご参照ください。
N 個のパーティション列を持つベクターパーティションキーが、ルーティングに最初の K 列 (1 ≤ K ≤ N) を使用する場合、WHERE 句にプレフィックスパーティション列 (最初の K 列) の条件を含めることで、パーティションプルーニングが可能になります。
例 1-2:ハッシュパーティショニング
ユーザー ID をパーティションキーとして水平パーティショニングに使用するには、ハッシュパーティショニングを使用してテーブルを作成し、8 つのパーティションを指定します:
CREATE TABLE hash_tbl(
id bigint not null auto_increment,
bid int,
name varchar(30),
birthday datetime not null,
primary key(id)
)
partition by hash(id)
partitions 8;
ハッシュパーティショニングは、YEAR() や TO_DAYS() などのパーティション関数式をサポートし、時間型の値を整数型に変換します。たとえば、birthday 列でテーブルを 8 つのハッシュパーティションに分割するには、次のステートメントを使用します:
CREATE TABLE hash_tbl_todays(
id bigint not null auto_increment,
bid int,
name varchar(30),
birthday datetime not null,
primary key(id)
)
PARTITION BY HASH(TO_DAYS(birthday))
PARTITIONS 8;
現在、PolarDB-X は以下のパーティション関数をサポートしています:
-
YEAR
-
MONTH
-
DAYOFMONTH
-
DAYOFWEEK
-
DAYOFYEAR
-
TO_DAYS
-
TO_MONTHS
-
TO_WEEKS
-
TO_SECONDS
-
UNIX_TIMESTAMP
-
SUBSTR/SUBSTRING
SUBSTR/SUBSTRING 関数の場合、パーティションキーは文字列型である必要があります。他のすべてのパーティション関数の場合、時間型 (DATE、DATETIME、TIMESTAMP など) である必要があります。
例 1-3:ハッシュパーティションの拡張
PolarDB-X は、ハッシュパーティショニング構文を拡張してベクターパーティションキーをサポートします。ネイティブ MySQL の標準パーティショニング構文とは異なり、PolarDB-X では HASH メソッドで複数の列によるパーティショニングが可能です。次のステートメントを使用します:
CREATE TABLE hash_tbl2(
id bigint not null auto_increment,
bid int,
name varchar(30),
birthday datetime not null,
primary key(id)
)
PARTITION BY HASH(name, birthday)
PARTITIONS 8;
KEY パーティショニングとは異なり、ハッシュパーティショニングはベクターパーティションキーを使用し、パーティションルーティング中にすべてのパーティション列がハッシュ計算とルーティング計算の両方に寄与します。したがって、パーティションプルーニングを有効にするには、SQL クエリの WHERE 句ですべてのパーティション列の等価条件を指定する必要があります。たとえば、SQL1 は hash_tbl2 テーブルでパーティションプルーニングをトリガーできますが、SQL2 はできません:
##SQL1 (このクエリはパーティションプルーニングをトリガーし、単一のパーティションのみをスキャンします)
SELECT id from hash_tbl2 where name='Jack' and birthday='1990-11-11';
##SQL2 (このクエリはパーティションプルーニングをトリガーせず、フルパーティションスキャンになります)
SELECT id from hash_tbl2 where name='Jack';
ハッシュパーティショニングは、事前にパーティションキー全体を使用してハッシュ値を計算するため、理論的にはベクターパーティショニングキーを使用するKEY パーティショニングよりもデータを均等に分散します。しかし、ホットパーティションを分割するための後続の列がないため、ホットスポット分割をサポートできません。
制限事項
-
データ型の制限
-
整数型:
BIGINT、BIGINT UNSIGNED、INT、INT UNSIGNED、MEDIUMINT、MEDIUMINT UNSIGNED、SMALLINT、SMALLINT UNSIGNED、TINYINT、およびTINYINT UNSIGNED。 -
時間型:
DATETIME、DATE、およびTIMESTAMP。 -
文字列型:
CHARおよびVARCHAR。
-
-
構文の制限
-
ハッシュパーティションで単一列パーティションキーを持つパーティション関数を使用する場合、キーは時間型でなければなりません。
-
ハッシュパーティションのベクターパーティションキーは、パーティション関数やホットスポット分割をサポートしません。
-
デフォルトでは、パーティションの最大数は 8,192 です。
-
デフォルトでは、パーティション列の最大数は 5 です。
-
データ均一性
-
KEY パーティショニングとハッシュパーティショニングの組み込み一貫性ハッシュアルゴリズムは MurmurHash3 であり、これは高性能で衝突確率の低いアルゴリズムです。
-
MurmurHash3 を使用すると、KEY パーティショニングとハッシュパーティショニングのデータ分布は、通常、一意のパーティションキー値の数 (N) が 3000 を超えた場合にのみ均等になります。N の値が大きいほど、データ分布はより均等になります。
RANGE タイプ
PolarDB-X では、RANGE パーティショニングには RANGE パーティションと RANGE COLUMNS パーティションの 2 種類があります。どちらもネイティブ MySQL の標準パーティショニング構文の一部です。次の表は、これら 2 つのパーティションタイプを比較したものです。
表 2. RANGE COLUMNS と RANGE パーティショニング戦略の比較
|
パーティショニング戦略 |
パーティションキーのサポート |
パーティション関数のサポート |
構文例 |
特徴と制限事項 |
ルーティング (ポイントクエリ) |
|
Range Columns |
単一列およびベクターパーティションキー |
いいえ |
PARTITION BY RANGE COLUMNS (c1,c2,...,cn) ( PARTITION p1 VALUES LESS THAN (1,10,...,1000), PARTITION p2 VALUES LESS THAN (2,20,...,2000) ...) |
ホットスポット分割をサポートします。たとえば、列 |
|
|
Range |
単一列パーティションキー |
はい |
PARTITION BY RANGE(YEAR(c1)) ( PARTITION p1 VALUES LESS THAN (2019), PARTITION p2 VALUES LESS THAN (2021) ...) |
|
|
例 2-1:RANGE COLUMNS パーティショニング
RANGE COLUMNS パーティショニングはベクターパーティションキーをサポートしますが、パーティション関数はサポートしません。たとえば、注文 ID と注文日でテーブルをパーティショニングするには、次の CREATE TABLE 構文を使用できます:
CREATE TABLE orders(
order_id int,
order_time datetime not null)
PARTITION BY RANGE COLUMNS(order_id,order_time)
(
PARTITION p1 VALUES LESS THAN (10000,'2021-01-01'),
PARTITION p2 VALUES LESS THAN (20000,'2021-01-01'),
PARTITION p3 VALUES LESS THAN (30000,'2021-01-01'),
PARTITION p4 VALUES LESS THAN (40000,'2021-01-01'),
PARTITION p5 VALUES LESS THAN (50000,'2021-01-01'),
PARTITION p6 VALUES LESS THAN (MAXVALUE,MAXVALUE)
);
RANGE COLUMNS パーティショニングは、TIMESTAMP や TIME などのタイムゾーン対応のデータ型をパーティションキーとしてサポートしません。
例 2-2:RANGE パーティショニング
RANGE パーティショニングは単一列パーティションキーのみをサポートします。ただし、datetime パーティション列の場合、YEAR、TO_DAYS、TO_SECONDS、MONTH などのパーティション関数を使用して、その値を整数に変換できます。
RANGE パーティショニングは、文字列型をパーティショニング列として直接サポートしません。
たとえば、RANGE パーティショニングを使用して order_time 列に四半期ごとのパーティションを作成するには、次の構文を使用します:
CREATE TABLE orders_todays(
id int,
order_time datetime not null)
PARTITION BY RANGE(to_days(order_time))
(
PARTITION p1 VALUES LESS THAN (to_days('2021-01-01')),
PARTITION p2 VALUES LESS THAN (to_days('2021-04-01')),
PARTITION p3 VALUES LESS THAN (to_days('2021-07-01')),
PARTITION p4 VALUES LESS THAN (to_days('2021-10-01')),
PARTITION p5 VALUES LESS THAN (to_days('2022-01-01')),
PARTITION p6 VALUES LESS THAN (MAXVALUE)
);
RANGE パーティショニングは、パーティションキーとして単一の整数型列のみをサポートします。
使用制限
-
データ型の制限
-
整数型:
BIGINT、BIGINT UNSIGNED、INT、INT UNSIGNED、MEDIUMINT、MEDIUMINT UNSIGNED、SMALLINT、SMALLINT UNSIGNED、TINYINT、およびTINYINT UNSIGNED。 -
日時型:
DATETIMEおよびDATE。 -
文字列型:
CHARおよびVARCHAR。
-
-
構文の制限
-
RANGE COLUMNSパーティショニングおよびRANGEパーティショニングは、境界値としてNULL値の使用をサポートしません。 -
RANGE COLUMNSパーティショニングはTIMESTAMPデータ型をサポートしません。 -
RANGEパーティショニングは整数型のみをサポートします。パーティショニングキーがTIMESTAMP型を使用する場合、タイムゾーンの一貫性を確保するためにUNIX_TIMESTAMP関数を使用する必要があります。 -
RANGEパーティショニングはホットスポット分割をサポートしません。 -
クエリ中、
NULL値はパーティションルーティングの最小値として扱われます。 -
デフォルトでは、パーティションの最大数は 8,192 です。
-
デフォルトでは、パーティショニング列の最大数は 5 です。
-
LIST タイプ
RANGE タイプと同様に、PolarDB-X はさらに LIST パーティショニングポリシーを LIST パーティショニングと LIST COLUMNS パーティショニングの 2 種類に細分化します。どちらのタイプもネイティブ MySQL の標準パーティショニング構文を使用します。さらに、PolarDB-X は LIST パーティショニングと LIST COLUMNS パーティショニングの両方でデフォルトパーティションをサポートします。この表はこれら 2 つのタイプを比較したものです:
表 3. LIST COLUMNS と LIST パーティショニング戦略の比較
|
パーティショニング戦略 |
パーティションキーのサポート |
パーティション関数のサポート |
構文例 |
特徴と制限事項 |
ルーティング (ポイントクエリ) |
|
List Columns |
単一列パーティションキーとベクターパーティションキー |
いいえ |
PARTITION BY LIST COLUMNS (c1,c2,...,cn) ( PARTITION p1 VALUES IN ((1,10,...,1000),(2,20,...,2000) ), PARTITION p2 VALUES IN ((3,30,...,3000),(3,30,...,3000) ), ...) |
ホットスポット分割はサポートされていません。 |
|
|
List |
単一列パーティションキー |
はい |
PARTITION BY LIST(YEAR(c1)) ( PARTITION p1 VALUES IN (2018,2019), PARTITION p2 VALUES IN (2020,2021) ...) |
ホットスポット分割はサポートされていません。 |
例 3-1:LIST COLUMNS パーティショニング
LIST COLUMNS パーティショニングはベクターパーティションキーをサポートします。たとえば、LIST COLUMNS パーティショニングを使用すると、国と都市で注文をパーティショニングできます。テーブル作成構文は次のとおりです:
CREATE TABLE orders_region(
id int,
country varchar(64),
city varchar(64),
order_time datetime not null)
PARTITION BY LIST COLUMNS(country,city)
(
PARTITION p1 VALUES IN (('China','Hangzhou'), ('China','Beijing')),
PARTITION p2 VALUES IN (('United States','New York'),('United States','Chicago')),
PARTITION p3 VALUES IN (('Russia','Moscow'))
);
LIST COLUMNS パーティショニングは現在、TIMESTAMP や TIME などのタイムゾーン情報を持つデータ型をパーティションキーとしてサポートしていません。
例 3-2:LIST パーティショニング
LIST パーティショニングは単一列パーティションキーのみをサポートしますが、時間型のパーティション列の場合、YEAR、MONTH、DAYOFMONTH、TO_DAYS、TO_SECONDS などのパーティション関数式を使用して、その値を整数型に変換できます。
たとえば、order_time 列の年に基づいてLIST パーティションを作成するには、次のcreate table 構文を使用します:
CREATE TABLE orders_years(
id int,
country varchar(64),
city varchar(64),
order_time datetime not null)
PARTITION BY LIST(YEAR(order_time))
(
PARTITION p1 VALUES IN (1990,1991,1992,1993,1994,1995,1996,1997,1998,1999),
PARTITION p2 VALUES IN (2000,2001,2002,2003,2004,2005,2006,2007,2008,2009),
PARTITION p3 VALUES IN (2010,2011,2012,2013,2014,2015,2016,2017,2018,2019)
);
パーティショニングはパーティションキーとして整数型のみをサポートします。文字列型はパーティション列としてサポートされていません。
例 3-3:デフォルトパーティションを持つ LIST COLUMNS および LIST パーティション
PolarDB-X は、通常のパーティションで定義されていないデータがルーティングされるデフォルトパーティションを含むLIST COLUMNS パーティションおよびLIST パーティションの作成をサポートします。
最大で 1 つのデフォルトパーティションを定義でき、それは最後のパーティションでなければなりません。
CREATE TABLE orders_region(
id int,
country varchar(64),
city varchar(64),
order_time datetime not null)
PARTITION BY LIST COLUMNS(country,city)
(
PARTITION p1 VALUES IN (('China','Hangzhou'), ('China','Beijing')),
PARTITION p2 VALUES IN (('United States','New York'),('United States','Chicago')),
PARTITION p3 VALUES IN (('Russia','Moscow')),
PARTITION pd VALUES IN (DEFAULT)
);
CREATE TABLE orders_years(
id int,
country varchar(64),
city varchar(64),
order_time datetime not null)
PARTITION BY LIST(YEAR(order_time))
(
PARTITION p1 VALUES IN (1990,1991,1992,1993,1994,1995,1996,1997,1998,1999),
PARTITION p2 VALUES IN (2000,2001,2002,2003,2004,2005,2006,2007,2008,2009),
PARTITION p3 VALUES IN (2010,2011,2012,2013,2014,2015,2016,2017,2018,2019),
PARTITION pd VALUES IN (DEFAULT)
);
使用制限
-
データ型の制限
-
整数型:BIGINT、BIGINT UNSIGNED、INT、INT UNSIGNED、MEDIUMINT、MEDIUMINT UNSIGNED、SMALLINT、SMALLINT UNSIGNED、TINYINT、および TINYINT UNSIGNED。
-
時間型:DATETIME および DATE。
-
文字列型:CHAR および VARCHAR。
-
-
構文の制限
-
LIST COLUMNS パーティショニングは TIMESTAMP データ型をサポートしません。
-
LIST パーティショニングは整数型のみをサポートします。
-
LIST COLUMNS パーティショニングも LIST パーティショニングもホットスポット分割をサポートしません。
-
デフォルトでは、パーティションの最大数は 8,192 です。
-
デフォルトでは、パーティション列の最大数は 5 です。
-
CoHash タイプ
PolarDB-X の CoHash パーティショニングポリシーは、PolarDB-X 独自のパーティショニングポリシーです。
バージョン要件
バージョン 5.4.18-17047709 以降を使用してください。
ユースケース
このパーティショニング戦略は、一般的に以下のビジネスシナリオで使用されます:
テーブルに相関する列、たとえば最後の 4 文字が常に同一である c1 と c2 がある場合、両方の列で水平にパーティショニングして、どちらかの列に等価条件を持つ SQL クエリを単一のパーティションにルーティングできます。
したがって、このパーティショニング戦略では、同じパーティションテーブル内の複数のパーティション列間で値が一貫している必要があります。
例 4-1:独立したパーティション関数でコロケーションを定義する
アプリケーションに orders テーブルがあり、各行の order_id と buyer_id 列が同じ最後の 6 桁を共有しているとします。このテーブルをこれらの共有された数字でパーティショニングし、どちらかの列に対する等価クエリが同じパーティションにルーティングされるようにするには、次の構文を使用します:
CREATE TABLE t_orders(
id bigint not null auto_increment,
order_id bigint,
buyer_id bigint,
order_time datetime not null,
primary key(id)
)
PARTITION BY CO_HASH(
RIGHT(`order_id`,6) /* order_id の最後の 6 文字 */,
RIGHT(`buyer_id`,6) /* buyer_id の最後の 6 文字 */
)
PARTITIONS 8;
例 4-2:1.0 から 2.0 へのユーザー移行に RANGE_HASH 糖衣構文を使用する
1.0 から 2.0 への移行では、range_hash を使用してデータベースとテーブルでシャーディングされた orders テーブルを考えます。これは次のように定義されます:DBPARTIITION BY RANGE_HASH(`order_id`,`buyer_id`, 6) 。2.0 AUTO データベース内の対応するパーティションテーブルは次のように定義されます:
CREATE TABLE orders(
id bigint not null auto_increment,
buyer_id bigint,
order_id bigint,
...
primary key(id)
)
PARTITION BY RANGE_HASH(order_id, buyer_Id,6)
PARTITIONS 8;
PolarDB-X は RANGE_HASH 構文を自動的に CO_HASH パーティション定義に変換します。たとえば、RANGE_HASH(order_id, buyer_Id, 6) は次の CO_HASH 定義になります:
CREATE TABLE orders(
id bigint not null auto_increment,
buyer_id bigint,
order_id bigint,
...
primary key(id)
)
PARTITION BY CO_HASH(
RIGHT(`order_id`,6) /* order_id の最後の 6 文字を使用 */,
RIGHT(`buyer_id`,6) /* buyer_id の最後の 6 文字を使用 */
)
PARTITIONS 8;
ハッシュ/KEY パーティショニングとの主な違い
CoHash とハッシュ/KEY パーティショニング戦略は似ているため、このセクションでは使用上の主な類似点と相違点を概説します。
|
主な違い |
CO_HASH |
KEY |
HASH |
|
構文例 |
PARTITION BY CO_HASH(c1, c2) PARTITIONS 8 |
PARTITION BY KEY(c1, c2) PARTITIONS 8 |
PARTITION BY HASH(c1, c2) PARTITIONS 8 |
|
単一列パーティションキー |
非サポート |
サポート |
サポート |
|
ベクターパーティションキー |
サポート |
サポート |
サポート |
|
ベクターパーティション列でのパーティション関数の使用 |
サポート。例: PARTITION BY CO_HASH( c1 の最後の 4 文字を抽出 RIGHT(c1, 4), / c2 の最後の 4 文字を抽出 / RIGHT(c2, 4) ) PARTITIONS 8 |
非サポート |
非サポート |
|
パーティション列間の関係 |
コロケーション関係。アプリケーションは、パーティション列の値間のこの関係を提供し、維持する必要があります。例:
|
複合インデックスのプレフィックス関係に似ています。 |
複合インデックスのプレフィックス関係に似ています。 |
|
プレフィックス列の等価クエリに対するパーティションプルーニング |
サポート。例:
|
サポート。例:
|
非サポート。パーティションプルーニングには、すべてのパーティション列に対する等価条件が必要です。例:
|
|
非プレフィックス列の等価クエリに対するパーティションプルーニング |
サポート。任意のパーティション列に対する等価条件は、独立してパーティションプルーニングをトリガーできます。例:
|
非サポート。非プレフィックスパーティション列に対する等価条件は、フルパーティションスキャンを必要とします。例:
|
非サポート。非プレフィックスパーティション列に対する等価条件は、フルパーティションスキャンを必要とします。例:
|
|
範囲クエリ |
非サポート。フルパーティションスキャンになります。 |
非サポート。フルパーティションスキャンになります。 |
非サポート。フルパーティションスキャンになります。 |
|
ルーティングの説明 (ポイントクエリ) |
|
上記の行にある KEY と HASH パーティショニングの比較をご参照ください。 |
上記の行にある KEY と HASH パーティショニングの比較をご参照ください。 |
|
ホットスポット分割 |
非サポート。 |
サポート |
非サポート |
|
パーティション管理 (例:パーティション分割、マージ、移行) |
サポート |
サポート |
サポート |
|
サブパーティショニング |
サポート |
サポート |
サポート |
考慮事項
-
サービスはパーティション列の値間の協調関係を維持する必要があります。PolarDB-X はルーティング結果のみを検証します。
CO_HASHパーティショニングを使用する場合、PolarDB-X は行の指定されたすべてのパーティション列の値が同じシャードにルーティングされることを検証します。ただし、値自体が協調関係に従っているかどうかは検証しません。この強制はサービスの責任です。たとえば、サービスが列 c1 と c2 の最後の 4 文字が同一であることを要求するとします。c1 の値 (100234 など) と c2 の値 (1320 など) が両方ともシャード 0 にルーティングされる場合、PolarDB-X はルーティングが一貫しているため、
insert (c1,c2) values (100234,1320)操作を許可します。しかし、この操作は c1 (0234) と c2 (1320) の最後の 4 文字が同じではないため、サービスルールに違反します。
-
パーティション列を変更する DML の制限 CO_HASH パーティショニングは複数のパーティション列の値を相関させるため、PolarDB-X は不正確なデータ分散を防ぐために、これらの列を変更する DML 操作に以下の制限を課します:
-
insert および replace ステートメントの場合、
VALUES句の単一行で異なるパーティション列の値が異なるパーティションに解決される場合、PolarDB-X は操作を拒否します。 -
update および upsert ステートメントの場合、
SET句ですべてのパーティション列を同時に変更する必要があります。たとえば、c1 と c2 がパーティション列の場合、UPDATE t1 SET c1='xx',c2='yy' WHERE id=1のようなステートメントを使用する必要があります。単一行で異なるパーティション列の新しい値が異なるパーティションに解決される場合、PolarDB-X はステートメントを拒否します。 -
CO_HASH がグローバルセカンダリインデックス (GSI) のパーティショニング戦略である場合、PolarDB-X は、単一の GSI 行で異なるパーティション列の値が異なるパーティションに解決される原因となるプライマリテーブルに対する DML 操作も拒否します。
-
-
整数型の先行ゼロの処理。
CO_HASH戦略のパーティション列は相関しているため、多くの場合、SUBSTR、LEFT、RIGHTなどのパーティション関数を使用して定義されます。このプロセスにより、整数が切り捨てられるときに先行ゼロが発生する可能性があります。たとえば、ビジネスロジックがc1とc2の最後の 4 文字が同一であることを要求するとします。c1が1000034の場合、最後の 4 文字は文字列'0034'です。整数型のパーティション列の場合、CO_HASHはルーティング前に切り捨てられた値をその列の整数型に自動的にキャストします。その結果、CO_HASHは文字列'0034'を整数34にキャストし、ハッシュ値を計算して行をルーティングします。このプロセスは先行ゼロを自動的に処理します。
パーティション関数の制限
-
RIGHT
-
LEFT
-
SUBSTR
データ型の制限
-
整数型:BIGINT、BIGINT UNSIGNED、INT、INT UNSIGNED、MEDIUMINT、MEDIUMINT UNSIGNED、SMALLINT、SMALLINT UNSIGNED、TINYINT、および TINYINT UNSIGNED
-
固定小数点型:DECIMAL (スケール 0)
-
時間型:非サポート
-
文字列型:CHAR および VARCHAR
構文の制限
-
パーティション列に
SUBSTR(SUBSTR(c1,-6),-4)のようなネストされたパーティション関数を使用することはできません。
-
RANGE_HASH糖衣構文を使用する場合、length パラメーターは負であってはなりません。 -
すべてのパーティション列は、以下のプロパティを含め、まったく同じデータ型でなければなりません:
-
文字セットと照合順序
-
長さと精度
-
-
デフォルトでは、パーティションの最大数は 8,192 です。
-
デフォルトでは、パーティション列の最大数は 5 です。
サブパーティション
MySQL と同様に、PolarDB-X はサブパーティショニング構文をサポートし、サブパーティションを持つパーティションテーブルを作成します。サブパーティショニングは、指定されたパーティショニング列とパーティショニング戦略に基づいて各パーティションをさらに分割します。
-
2 レベルのパーティションテーブルでは、各第 1 レベルのパーティションは、第 2 レベルのパーティションのセットにマッピングされる論理パーティションです。
-
各第 2 レベルのパーティションは、DN ノード上の特定の物理テーブルシャードにマッピングされる物理パーティションです。
テンプレート化と非テンプレート化
PolarDB-X の第 2 レベルのパーティションは、テンプレート化と非テンプレート化の 2 つの主要なカテゴリに分類されます:
-
テンプレート化されたサブパーティション:サブパーティションの数とそのパーティション境界値は、すべてのパーティションで同じです。
-
非テンプレート化されたサブパーティション:サブパーティションの数とそのパーティション境界値は、各パーティションで異なる場合があります。
構文の制限
-
デフォルトでは、サブパーティショニングを使用するパーティションテーブルは 8,192 を超える物理パーティションを持つことはできません。
-
非テンプレート化されたパーティションを使用する場合、すべてのサブパーティション名は一意でなければならず、どのパーティション名とも一致してはなりません。
-
テンプレート化されたパーティションを使用する場合、テンプレート内のすべてのサブパーティション名は一意でなければならず、どのパーティション名とも一致してはなりません。
-
サブパーティショニングでは、テーブル内の物理パーティションの総数は、すべてのパーティションにわたるサブパーティションの総数です。この数は急速に増加する可能性があります。したがって、パーティションの過剰分割によるパフォーマンスの低下や、総パーティション制限の超過によるエラーを避けるために、パーティションとサブパーティションの数を慎重に管理してください。
例 5-1:テンプレート化されたセカンダリパーティション
/*
* この例では、LIST-KEY 複合戦略を使用してテンプレート化されたサブパーティションを定義します。
* テーブルはまず LIST COLUMNS によって 3 つのパーティションに分割されます。
* 各パーティションは次に KEY によって 4 つのサブパーティションにサブパーティション化され、合計 12 の物理パーティションになります。
*/
CREATE TABLE sp_tbl_list_key_tp(
id int,
country varchar(64),
city varchar(64),
order_time datetime not null,
PRIMARY KEY(id)
)
PARTITION BY LIST COLUMNS(country,city)
SUBPARTITION BY KEY(id) SUBPARTITIONS 4
(
PARTITION p1 VALUES IN (('China','Hangzhou')),
PARTITION p2 VALUES IN (('Russian','Moscow')),
PARTITION pd VALUES IN (DEFAULT)
);
例 5-2:非テンプレート化されたサブパーティション
/*
* この例では、LIST-KEY 複合戦略を使用して非テンプレート化されたサブパーティションを定義します。
* テーブルは LIST COLUMNS によって 3 つの第 1 レベルのパーティションに分割され、それぞれが KEY によってサブパーティション化されます。
* 第 1 レベルのパーティションには、それぞれ 2、3、4 つのサブパーティションがあります。
* これにより、合計 9 つの物理パーティション (2 + 3 + 4) になります。
*/
CREATE TABLE sp_tbl_list_key_ntp(
id int,
country varchar(64),
city varchar(64),
order_time datetime not null,
PRIMARY KEY(id)
)
PARTITION BY LIST COLUMNS(country,city)
SUBPARTITION BY KEY(id)
(
PARTITION p1 VALUES IN (('China','Hangzhou')) SUBPARTITIONS 2,
PARTITION p2 VALUES IN (('Russia','Moscow')) SUBPARTITIONS 3,
PARTITION pd VALUES IN (DEFAULT) SUBPARTITIONS 4
);
自動パーティショニング
デフォルトでは、AUTO モードのデータベースでは自動パーティショニングは無効になっています。この機能を有効にするには、次のコマンドを実行します:
SET GLOBAL AUTO_PARTITION=true;
自動パーティショニングを有効にすると:
-
パーティショニングキーを指定せずにテーブルを作成すると、PolarDB-X はデフォルトでそのプライマリキーを使用してテーブルをパーティショニングします。テーブルにプライマリキーがない場合は、代わりに暗黙の主キーを使用します。このプロセスでは KEY パーティショニングが使用され、レベル 1 のパーティションテーブルが作成されます。
デフォルトでは、パーティションの数はインスタンス内の論理ノードの数の 8 倍です。たとえば、PolarDB-X インスタンスが 2 つの論理ノードで作成された場合、デフォルトのパーティション数は 16 です。
-
プライマリテーブルのパーティショニングに加えて、PolarDB-X はデフォルトですべてのインデックスもパーティショニングします。インデックスのパーティショニングキーは、インデックス列とテーブルのプライマリキー列で構成されます。
次の例は、テーブルを作成するための標準的な MySQL 構文を示しています。ここで、id はプライマリキー、name はインデックス付き列です:
CREATE TABLE auto_part_tbl(
id bigint not null auto_increment,
bid int,
name varchar(30),
primary key(id),
index idx_name (name)
);
SHOW CREATE TABLE ステートメントを実行すると、標準の MySQL テーブル作成構文が表示され、すべてのパーティション情報が自動的に非表示になります:
show create table auto_part_tbl;
+---------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| TABLE | CREATE TABLE |
+---------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| auto_part_tbl | CREATE TABLE `auto_part_tbl` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`bid` int(11) DEFAULT NULL,
`name` varchar(30) DEFAULT NULL,
PRIMARY KEY (`id`),
INDEX `idx_name` (`name`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8 |
+---------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.06 sec)
SHOW FULL CREATE TABLE ステートメントを実行すると、メインテーブルとそのインデックステーブルのすべてのパーティション情報が表示されます:
show full create table auto_part_tbl;
+---------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| TABLE | CREATE TABLE |
+---------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| auto_part_tbl | CREATE PARTITION TABLE `auto_part_tbl` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`bid` int(11) DEFAULT NULL,
`name` varchar(30) DEFAULT NULL,
PRIMARY KEY (`id`),
GLOBAL INDEX /* idx_name_$a870 */ `idx_name` (`name`) PARTITION BY KEY (`name`, `id`) PARTITIONS 16,
LOCAL KEY `_local_idx_name` (`name`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8
PARTITION BY KEY(`id`)
PARTITIONS 16
/* table group = `tg108` */ |
+---------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.03 sec)
出力は次のことを示しています:
-
デフォルトでは、メインテーブル
auto_part_tblはid列でKEYパーティショニングを使用して 16 のパーティションに分割されます。 -
デフォルトでは、メインテーブルのインデックス
idx_nameは、nameとid列をパーティショニングキーとして使用し、16 のパーティションを持つグローバルインデックスです。
手動パーティショニング
CREATE TABLE ステートメントでパーティション列、パーティション関数、およびパーティションタイプを指定することで、手動でパーティション化されたテーブルを作成できます。パーティションタイプの詳細については、「パーティションテーブルを手動で作成する (AUTO モード)」をご参照ください。
データ型
表 4. パーティショニングタイプ別のパーティションキー列でサポートされるデータ型
|
データ型 |
ハッシュパーティショニング |
RANGE パーティショニング |
LIST パーティショニング |
|||||
|
Hash |
Key |
Range |
Range columns |
List |
List columns |
|||
|
単一パーティションキー列 |
複数パーティションキー列 |
|||||||
|
整数型 |
TINYINT |
|
|
|
|
|
|
|
|
TINYINT UNSIGNED |
|
|
|
|
|
|
|
|
|
SMALLINT |
|
|
|
|
|
|
|
|
|
SMALLINT UNSIGNED |
|
|
|
|
|
|
|
|
|
MEDIUMINT |
|
|
|
|
|
|
|
|
|
MEDIUMINT UNSIGNED |
|
|
|
|
|
|
|
|
|
INT |
|
|
|
|
|
|
|
|
|
INT UNSIGNED |
|
|
|
|
|
|
|
|
|
BIGINT |
|
|
|
|
|
|
|
|
|
BIGINT UNSIGNED |
|
|
|
|
|
|
|
|
|
固定小数点型 |
DECIMAL |
(パーティション関数は非対応) |
|
|
|
|
|
|
|
日付と時刻の型 |
DATE |
|
|
|
|
|
|
|
|
DATETIME |
|
|
|
|
|
|
|
|
|
TIMESTAMP |
|
|
|
|
|
|
|
|
|
文字列型 |
CHAR |
|
|
|
|
|
|
|
|
VARCHAR |
|
|
|
|
|
|
|
|
|
バイナリ型 |
BINARY |
|
|
|
|
|
|
|
|
VARBINARY |
|
|
|
|
|
|
|
|
パーティションキーのデータ型とルーティング
パーティションテーブルのルーティングは、パーティションキーのデータ型に直接依存します。特に KEY パーティションとハッシュパーティションで顕著です。データ型が異なると、使用されるハッシュアルゴリズムや比較ロジック (大文字と小文字の区別など) が異なり、ルーティングの動作も異なります。(注:MySQL のパーティションルーティングも型に強く依存します。)
この例では、tbl_int と tbl_bigint の 2 つのテーブルを示します。どちらも 1,024 のパーティションを持ちます。tbl_int テーブルは int パーティションキーを使用し、tbl_bigint は bigint パーティションキーを使用します。どちらも整数型ですが、この違いにより、同じクエリ値 (12345678) が異なるパーティションにルーティングされます:
show create table tbl_int;
+---------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| TABLE | CREATE TABLE |
+---------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| tbl_int | CREATE TABLE `tbl_int` (
`a` int(11) NOT NULL,
KEY `auto_shard_key_a` USING BTREE (`a`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4
PARTITION BY KEY(`a`)
PARTITIONS 1024 |
+---------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.02 sec)
show create table tbl_bigint;
+------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| TABLE | CREATE TABLE |
+------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| tbl_bigint | CREATE TABLE `tbl_bigint` (
`a` bigint(20) NOT NULL,
KEY `auto_shard_key_a` USING BTREE (`a`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4
PARTITION BY KEY(`a`)
PARTITIONS 1024 |
+------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.10 sec)mysql> create table if not exists tbl_bigint(a bigint not null)
-> partition by key(a) partitions 1024;
Query OK, 0 rows affected (28.41 sec)
explain select * from tbl_int where a=12345678;
+---------------------------------------------------------------------------------------------------+
| LOGICAL EXECUTIONPLAN |
+---------------------------------------------------------------------------------------------------+
| LogicalView(tables="tbl_int[p260]", sql="SELECT `a` FROM `tbl_int` AS `tbl_int` WHERE (`a` = ?)") |
| HitCache:false |
| Source:PLAN_CACHE |
| TemplateId: c90af636 |
+---------------------------------------------------------------------------------------------------+
4 rows in set (0.45 sec)
explain select * from tbl_bigint where a=12345678;
+------------------------------------------------------------------------------------------------------------+
| LOGICAL EXECUTIONPLAN |
+------------------------------------------------------------------------------------------------------------+
| LogicalView(tables="tbl_bigint[p477]", sql="SELECT `a` FROM `tbl_bigint` AS `tbl_bigint` WHERE (`a` = ?)") |
| HitCache:false |
| Source:PLAN_CACHE |
| TemplateId: 9b2fa47c |
+------------------------------------------------------------------------------------------------------------+
4 rows in set (0.02 sec)
大文字と小文字の区別、文字セット、照合順序
パーティションキーの文字セットと照合順序は、パーティションテーブルのルーティングアルゴリズムに直接影響します。たとえば、ルーティングで大文字と小文字を区別するかどうかを決定します。テーブルの照合順序で大文字と小文字が区別される場合、ルーティング中のハッシュ化と比較も大文字と小文字を区別します。逆に、照合順序で大文字と小文字が区別されない場合、これらの操作も大文字と小文字を区別しません。デフォルトでは、文字列パーティションキーは utf8 文字セットと、大文字と小文字を区別しない utf8_general_ci 照合順序を使用します。
例 1
パーティションキーのルーティングで大文字と小文字を区別するようにするには、テーブル作成時にテーブルの照合順序を utf8_bin のように大文字と小文字を区別するものに設定します。以下の例では、tbl_varchar_cs テーブルは CHARACTER SET utf8 COLLATE utf8_bin を使用しています。その結果、大文字と小文字のみが異なる文字列 'AbcD' と 'abcd' を異なるパーティションにルーティングします:
show create table tbl_varchar_cs;
+----------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| TABLE | CREATE TABLE |
+----------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| tbl_varchar_cs | CREATE TABLE `tbl_varchar_cs` (
`a` varchar(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
KEY `auto_shard_key_a` USING BTREE (`a`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8
PARTITION BY KEY(`a`)
PARTITIONS 64 |
+----------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.07 sec)
explain select a from tbl_varchar_cs where a in ('AbcD');
+-------------------------------------------------------------------------------------------------------------------------+
| LOGICAL EXECUTIONPLAN |
+-------------------------------------------------------------------------------------------------------------------------+
| LogicalView(tables="tbl_varchar_cs[p29]", sql="SELECT `a` FROM `tbl_varchar_cs` AS `tbl_varchar_cs` WHERE (`a` IN(?))") |
| HitCache:false |
| Source:PLAN_CACHE |
| TemplateId: 2c49c244 |
+-------------------------------------------------------------------------------------------------------------------------+
4 rows in set (0.11 sec)
explain select a from tbl_varchar_cs where a in ('abcd');
+-------------------------------------------------------------------------------------------------------------------------+
| LOGICAL EXECUTIONPLAN |
+-------------------------------------------------------------------------------------------------------------------------+
| LogicalView(tables="tbl_varchar_cs[p11]", sql="SELECT `a` FROM `tbl_varchar_cs` AS `tbl_varchar_cs` WHERE (`a` IN(?))") |
| HitCache:true |
| Source:PLAN_CACHE |
| TemplateId: 2c49c244 |
+-------------------------------------------------------------------------------------------------------------------------+
4 rows in set (0.02 sec)
例 2
パーティションキーのルーティングで大文字と小文字を区別しないようにするには、テーブル作成時にテーブルの照合順序を utf8_general_ci のように大文字と小文字を区別しないものに設定します。以下の例では、tbl_varchar_ci テーブルは CHARACTER SET utf8 COLLATE utf8_general_ci を使用しています。その結果、文字列 'AbcD' と 'abcd' を同じパーティションにルーティングします:
show create table tbl_varchar_ci;
+----------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| TABLE | CREATE TABLE |
+----------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| tbl_varchar_ci | CREATE TABLE `tbl_varchar_ci` (
`a` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
KEY `auto_shard_key_a` USING BTREE (`a`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8
PARTITION BY KEY(`a`)
PARTITIONS 64 |
+----------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.06 sec)
explain select a from tbl_varchar_ci where a in ('AbcD');
+------------------------------------------------------------------------------------------------------------------------+
| LOGICAL EXECUTIONPLAN |
+------------------------------------------------------------------------------------------------------------------------+
| LogicalView(tables="tbl_varchar_ci[p4]", sql="SELECT `a` FROM `tbl_varchar_ci` AS `tbl_varchar_ci` WHERE (`a` IN(?))") |
| HitCache:false |
| Source:PLAN_CACHE |
| TemplateId: 5c97178e |
+------------------------------------------------------------------------------------------------------------------------+
4 rows in set (0.15 sec)
explain select a from tbl_varchar_ci where a in ('abcd');
+------------------------------------------------------------------------------------------------------------------------+
| LOGICAL EXECUTIONPLAN |
+------------------------------------------------------------------------------------------------------------------------+
| LogicalView(tables="tbl_varchar_ci[p4]", sql="SELECT `a` FROM `tbl_varchar_ci` AS `tbl_varchar_ci` WHERE (`a` IN(?))") |
| HitCache:true |
| Source:PLAN_CACHE |
| TemplateId: 5c97178e |
+------------------------------------------------------------------------------------------------------------------------+
4 rows in set (0.02 sec)
文字セットと照合順序の変更
パーティションテーブルのルーティングアルゴリズムは、そのパーティションキーのデータ型によって決定されるため、パーティションキーの文字セットや照合順序を変更すると、テーブル内のすべてのデータの再配布がトリガーされます。したがって、パーティションキーのデータ型を変更する際には注意が必要です。
パーティション列の型の切り捨てと変換
パーティション列の型の切り捨て
クエリや INSERT ステートメントの定数式がパーティション列のデータ型の有効範囲を超えた場合、PolarDB-X はまず値を切り捨ててから、ルーティング計算に使用します。
たとえば、tbl_smallint テーブルには smallint 型のパーティション列があり、その有効範囲は -32768 から 32767 です。この範囲外の値、たとえば 12345678 や -12345678 を挿入しようとすると、PolarDB-X はまず値を smallint 型の最大値または最小値 (それぞれ 32767 または -32768) に切り捨てます。次の例はこのプロセスを示しています。
show create table tbl_smallint;
+--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| TABLE | CREATE TABLE |
+--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| tbl_smallint | CREATE TABLE `tbl_smallint` (
`a` smallint(6) NOT NULL,
KEY `auto_shard_key_a` USING BTREE (`a`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4
PARTITION BY KEY(`a`)
PARTITIONS 128 |
+--------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.06 sec)
set sql_mode='';
Query OK, 0 rows affected (0.00 sec)
insert into tbl_smallint values (12345678),(-12345678);
Query OK, 2 rows affected (0.07 sec)
select * from tbl_smallint;
+--------+
| a |
+--------+
| -32768 |
| 32767 |
+--------+
2 rows in set (3.51 sec)
explain select * from tbl_smallint where a=12345678;
+------------------------------------------------------------------------------------------------------------------+
| LOGICAL EXECUTIONPLAN |
+------------------------------------------------------------------------------------------------------------------+
| LogicalView(tables="tbl_smallint[p117]", sql="SELECT `a` FROM `tbl_smallint` AS `tbl_smallint` WHERE (`a` = ?)") |
| HitCache:false |
| Source:PLAN_CACHE |
| TemplateId: afb464d5 |
+------------------------------------------------------------------------------------------------------------------+
4 rows in set (0.16 sec)
explain select * from tbl_smallint where a=32767;
+------------------------------------------------------------------------------------------------------------------+
| LOGICAL EXECUTIONPLAN |
+------------------------------------------------------------------------------------------------------------------+
| LogicalView(tables="tbl_smallint[p117]", sql="SELECT `a` FROM `tbl_smallint` AS `tbl_smallint` WHERE (`a` = ?)") |
| HitCache:true |
| Source:PLAN_CACHE |
| TemplateId: afb464d5 |
+------------------------------------------------------------------------------------------------------------------+
4 rows in set (0.03 sec)
同様に、クエリ内の定数値が型の範囲を超えた場合、PolarDB-X はルーティング前にそれを切り捨てます。したがって、tbl_smallint テーブルの場合、PolarDB-X は a=12345678 と a=32767 のクエリを同じパーティションにルーティングします。
パーティション列の型変換
クエリや INSERT ステートメントの定数式がパーティション列と異なるデータ型を持つ場合、PolarDB-X は定数式に対して暗黙の型変換を行い、変換された値をルーティング計算に使用します。ただし、型変換は失敗することがあります。たとえば、文字列 abc は整数に変換できません。
パーティション列の型変換が発生または失敗した場合、PolarDB-X はステートメントが DQL、DML、または DDL ステートメントであるかによって動作が異なります:
-
DQL(特にWHERE句のパーティション列に関わる型変換)-
変換成功:PolarDB-X は変換された値を
パーティションルーティングに使用します。 -
変換失敗:PolarDB-X は
パーティション列の条件を無視し、フルテーブルスキャンになります。
-
-
DML(特にINSERTまたはREPLACEステートメント)-
変換成功:PolarDB-X は変換された値を
パーティションルーティングに使用します。 -
変換失敗:PolarDB-X はステートメントを拒否し、エラーを返します。
-
-
DDL(特にパーティションテーブルに関連するDDLステートメント、たとえばCREATE TABLEやSPLIT PARTITION)-
変換成功:PolarDB-X はステートメントを拒否し、エラーを返します。
DDLステートメントは暗黙の型変換を許可しません。 -
変換失敗:PolarDB-X はステートメントを拒否し、エラーを返します。
-
MySQL パーティションテーブルとの構文の違い
|
違い |
MySQL |
PolarDB-X |
|
パーティショニングキーへのプライマリキーの包含 |
必須。 |
必須ではありません。 |
|
KEY パーティショニング |
ルーティングアルゴリズム:パーティション数に対する剰余演算。 |
ルーティングアルゴリズム:一貫性ハッシュアルゴリズム。 |
|
ハッシュパーティショニング |
|
|
|
パーティション関数 |
サポートされています。 |
制限付きでサポートされています。
|
|
パーティショニング列のデータ型 |
KEY パーティショニングはすべてのデータ型をサポートします。 |
KEY パーティショニングは、整数、日付と時刻、および文字列データ型のみをサポートします。 |
|
パーティショニング列の文字セット |
すべての一般的な文字セットをサポートします。 |
以下の文字セットのみをサポートします:
|
|
サブパーティショニング |
サポートされています。 |
サポートされています。 |
対応
非対応