サブパーティショニング、— もしくは
複合パーティショニング —
はパーティショニングされたテーブルのパーティションをさらに分けることを指します。例えば、以下の
CREATE TABLE
ステートメントを検討してください。
CREATE TABLE ts (id INT, purchased DATE) PARTITION BY RANGE( YEAR(purchased) ) SUBPARTITION BY HASH( TO_DAYS(purchased) ) SUBPARTITIONS 2 ( PARTITION p0 VALUES LESS THAN (1990), PARTITION p1 VALUES LESS THAN (2000), PARTITION p2 VALUES LESS THAN MAXVALUE );
テーブル ts
は3つの
RANGE
パーティショニングを含んでいます。これらの各パーティション
—
p0
、p1
、そして
p2
—
はさらに2つのサブパーティションに分けられます。結果的に、テーブル全体が
3 * 2 = 6
パーティションに分けられます。ただし、PARTITION
BY RANGE
節の作動によって、最初の2つは
purchased
カラムで 1990
の値より少ないレコードのみが記憶されます。
MySQL 5.1 では、RANGE
や
LIST
によってパーティショニングされたテーブルをさらにサブパーティショニングすることが可能です。サブパーティショニングは
HASH
または KEY
パーティショニングを用いることがあります。これは、複合パーティショニング
とも呼ばれます。
SUBPARTITION
節を使用して各々のサブパーティショニングのオプションを特定することで、サブパーティションを定義することができます。例えば、以前の例通りの
ts
を回りくどく作成する場合。
CREATE TABLE ts (id INT, purchased DATE) PARTITION BY RANGE( YEAR(purchased) ) SUBPARTITION BY HASH( TO_DAYS(purchased) ) ( PARTITION p0 VALUES LESS THAN (1990) ( SUBPARTITION s0, SUBPARTITION s1 ), PARTITION p1 VALUES LESS THAN (2000) ( SUBPARTITION s2, SUBPARTITION s3 ), PARTITION p2 VALUES LESS THAN MAXVALUE ( SUBPARTITION s4, SUBPARTITION s5 ) );
構文的な注意点:
各パーティションは同じ数のサブパーティションを擁していなければいけません。
もしパーティショニングされたテーブルにおいて
SUBPARTITION
を使用して明示的にサブパーティションを定義した場合、残る全てのパーティションにおいてもサブパーティションを定義しなければいけません。言い換えれば、以下のステートメントは失敗します。
CREATE TABLE ts (id INT, purchased DATE) PARTITION BY RANGE( YEAR(purchased) ) SUBPARTITION BY HASH( TO_DAYS(purchased) ) ( PARTITION p0 VALUES LESS THAN (1990) ( SUBPARTITION s0, SUBPARTITION s1 ), PARTITION p1 VALUES LESS THAN (2000), PARTITION p2 VALUES LESS THAN MAXVALUE ( SUBPARTITION s2, SUBPARTITION s3 ) );
このステートメントは、SUBPARTITIONS
2
節を含んでいたとしても失敗します。
各 SUBPARTITION
節は(最低でも)
サブパーティションの名称を含んでいなければいけません。でなければ、サブパーティションに要求どおりのオプションを設定するか、そのオプションのデフォルト設定にもどします。
MySQL 5.1.7
以前では、サブパーティションの名称は各パーティション内ではユニークである必要がありましたが、テーブル全体の中でユニークである必要はありませんでした。MySQL
5.1.8
に始まり、サブパーティション名称はテーブル全体においてユニークであることが必要になりました。たとえば、以下の
CREATE TABLE
ステートメントはMySQL 5.1.8以降有効です。
CREATE TABLE ts (id INT, purchased DATE) PARTITION BY RANGE( YEAR(purchased) ) SUBPARTITION BY HASH( TO_DAYS(purchased) ) ( PARTITION p0 VALUES LESS THAN (1990) ( SUBPARTITION s0, SUBPARTITION s1 ), PARTITION p1 VALUES LESS THAN (2000) ( SUBPARTITION s2, SUBPARTITION s3 ), PARTITION p2 VALUES LESS THAN MAXVALUE ( SUBPARTITION s4, SUBPARTITION s5 ) );
(以前のステートメントは MySQL 5.1.8. 以前でも有効です。)
サブパーティショニングはデータやインデックスを複数のディスク上分布するために特に大きなテーブルと使用することができます。例えば、/disk0
、/disk1
、/disk2
とつづく6つのディスクを重ねていたとします。以下の例を検討してください。
CREATE TABLE ts (id INT, purchased DATE) PARTITION BY RANGE( YEAR(purchased) ) SUBPARTITION BY HASH( TO_DAYS(purchased) ) ( PARTITION p0 VALUES LESS THAN (1990) ( SUBPARTITION s0 DATA DIRECTORY = '/disk0/data' INDEX DIRECTORY = '/disk0/idx', SUBPARTITION s1 DATA DIRECTORY = '/disk1/data' INDEX DIRECTORY = '/disk1/idx' ), PARTITION p1 VALUES LESS THAN (2000) ( SUBPARTITION s2 DATA DIRECTORY = '/disk2/data' INDEX DIRECTORY = '/disk2/idx', SUBPARTITION s3 DATA DIRECTORY = '/disk3/data' INDEX DIRECTORY = '/disk3/idx' ), PARTITION p2 VALUES LESS THAN MAXVALUE ( SUBPARTITION s4 DATA DIRECTORY = '/disk4/data' INDEX DIRECTORY = '/disk4/idx', SUBPARTITION s5 DATA DIRECTORY = '/disk5/data' INDEX DIRECTORY = '/disk5/idx' ) );
この場合、データと各 RANGE
インデックスごとに別のディスクが使用されています。他にもバリエーションが考えられます。例えば:
CREATE TABLE ts (id INT, purchased DATE) PARTITION BY RANGE(YEAR(purchased)) SUBPARTITION BY HASH( TO_DAYS(purchased) ) ( PARTITION p0 VALUES LESS THAN (1990) ( SUBPARTITION s0a DATA DIRECTORY = '/disk0' INDEX DIRECTORY = '/disk1', SUBPARTITION s0b DATA DIRECTORY = '/disk2' INDEX DIRECTORY = '/disk3' ), PARTITION p1 VALUES LESS THAN (2000) ( SUBPARTITION s1a DATA DIRECTORY = '/disk4/data' INDEX DIRECTORY = '/disk4/idx', SUBPARTITION s1b DATA DIRECTORY = '/disk5/data' INDEX DIRECTORY = '/disk5/idx' ), PARTITION p2 VALUES LESS THAN MAXVALUE ( SUBPARTITION s2a, SUBPARTITION s2b ) );
ここでは、ストレージは以下のようになります。
purchased
日付が1990
以前の行は大容量を必要とするため、4つに分けられています。これは別のディスクをデータと各サブパーティション専用に割り当て、(s0a
と s0b
) p0
パーティションを作成する。言い換えると:
サブパーティション s0a
のデータは /disk0
に記憶されています。
サブパーティション s0a
のインデックスは /disk01
に記憶されています。
サブパーティション s0b
のデータは /disk2
に記憶されています。
サブパーティション s0b
のインデックスは /disk3
に記憶されています。
1990 から1999を含む行は(パーティション
p1
) 1990
以前のものと比べ、容量を多く要求しません。p0
で記憶されている4つのディスクのレガシィレコードと比べ、これらは2つのディスク上振り分けられています。(/disk4
と /disk5
)
p1
の最初のサブパーティションに含まれるデータやインデックスは(s1a
)
は /disk4
に記憶され、
— /disk4/data
のデータ、/disk4/idx
内のインデックス
p1
の2番目ののサブパーティションに含まれるデータやインデックスは(s1b
)
は /disk5
に記憶され、
— /disk5/data
のデータ、/disk5/idx
内のインデックス
2000年から現在を示す(パーティション
p2
)
行は、以前の2レンジで必要とされたほどのスペースは要求されません。現在では、デフォルト位置にこれら全てを記憶することで事足ります。
将来的に、2000年から始まった購入のデータ量がデフォルト位置内で支えきれなくなった時、ALTER
TABLE ... REORGANIZE PARTITION
ステートメントを使用してそれらの行は移動させることができます。詳細については、項15.3. 「パーティショニング管理」
を参照してください。