MySQLのリスト分割は多くの点でレンジ分割に似ています。RANGE
による分割同様、各分割は明確に定義されていなければいけません。決定的な違いは、リスト分割では、隣接する値のレンジ内のセットの1つとしてではなく、各分割は1セットの値のリストの中のカラム値メンバーシップによって定義・選択されます。これは
PARTITION BYLIST
(
によって実行されます。その時
expr)expr
はカラム値もしくは返される整数値に基づいたカラム値や表現であり、VALUES
IN ( の
value_list)value_list
はカンマによって分けられた整数のリストになります。
注:MySQL
5.1では、LIST
による分割を行う時、整数のリストのみに対して照合(そして
NULL
—項15.2.6. 「MySQL分割の NULL 値の取り扱い」
を参照してください)をすることが可能です。
分割がレンジによって定義されたケースとは異なり、リスト分割は特定の順番で宣言される必要はありません。さらに詳しい構文に関する情報については、項12.1.8. 「CREATE TABLE 構文」
を参照してください。
以下の例では、分割されるテーブルの基本的な定義は
CREATE TABLE
ステートメントによって提供されているものとします。
CREATE TABLE employees (
id INT NOT NULL,
fname VARCHAR(30),
lname VARCHAR(30),
hired DATE NOT NULL DEFAULT '1970-01-01',
separated DATE NOT NULL DEFAULT '9999-12-31',
job_code INT,
store_id INT
);
(これは 項15.2.1. 「RANGE パーティショニング」
の例として使用されるテーブルと同様のものです。)
例えば、以下のテーブルの様に20のビデオレンタル店が4つのフランチャイズで分布されているとします。
| 地域 | 店舗ID |
| 北 | 3, 5, 6, 9, 17 |
| 東 | 1, 2, 10, 11, 19, 20 |
| 西 | 4, 12, 13, 14, 18 |
| 中央 | 7, 8, 15, 16 |
同じ地域の店舗を示す行が同分割含まれるようテーブルを分割する場合は、以下の様に
CREATE TABLE
ステートメントを使用することができます。
CREATE TABLE employees (
id INT NOT NULL,
fname VARCHAR(30),
lname VARCHAR(30),
hired DATE NOT NULL DEFAULT '1970-01-01',
separated DATE NOT NULL DEFAULT '9999-12-31',
job_code INT,
store_id INT
)
PARTITION BY LIST(store_id) (
PARTITION pNorth VALUES IN (3,5,6,9,17),
PARTITION pEast VALUES IN (1,2,10,11,19,20),
PARTITION pWest VALUES IN (4,12,13,14,18),
PARTITION pCentral VALUES IN (7,8,15,16)
);
これによって、テーブルから特定の地域の店舗の従業員情報を簡単に追加・削除することが可能になります。例えば、西地域の全店舗が別の会社に売られたとします。その地域で雇用されている従業員を示す全ての行は
ALTER TABLE employees DROP PARTITION pWest;
クエリを使用して削除することができ、これは同等の
DELETE ステートメントの
DELETE FROM employees WHERE store_id IN
(4,12,13,14,18);
よりはるかに効率よく実行することができます。
RANGE や HASH
分割のように、NULL
か整数ではない値を持つカラムでテーブルを分割する場合、そのような値を返すカラムに基づいてパーティショニング表現を使用する必要があります。例えば、以下のように従業員データを含むテーブルが記されていたとします。
CREATE TABLE employees (
id INT NOT NULL,
fname VARCHAR(30),
lname VARCHAR(30),
hired DATE NOT NULL DEFAULT '1970-01-01',
separated DATE NOT NULL DEFAULT '9999-12-31',
job_code CHAR(1),
store_id INT
);
この employees
テーブルのバージョンでは、雇用コードは数値ではなく文字になります。各文字が特定の職種に対応しており、同様の職種についている、もしくは同じ職場の従業員は同じ分割に含まれるよう、以下のスキーマでテーブルを分割したいとします。
| 職種・職場 | 雇用コード |
| 管理 | D, M, O, P |
| 営業 | B, L, S |
| 技術 | A, E, G, I, T |
| 事務 | K, N, Y |
| サポート | C, F, J, R, V |
| 割り振りなし | 「空」 |
値のリストでキャラクタ値がしようできないため、これらを整数もしくは
NULL
等に変換する必要があります。このため、ASCII()
関数をカラム値に使用することができます。加えて、—
異なる時間帯、ロケーションでの異なるアプリケーションの使用により、—
これらのコードは大文字、もしくは小文字になりえ、「割り振られていない」
を示す「空」
値は、NULL、空の文字列、もしくはスペースを表しているかもしれません。このスキーマを実装しているパーティションドテーブルが以下に示されています。
CREATE TABLE employees (
id INT NOT NULL,
fname VARCHAR(30),
lname VARCHAR(30),
hired DATE NOT NULL DEFAULT '1970-01-01',
separated DATE NOT NULL DEFAULT '9999-12-31',
job_code CHAR(1),
store_id INT
)
PARTITION BY LIST(ASCII( UCASE(job_code) )) (
PARTITION management VALUES IN(68, 77, 79, 80),
PARTITION sales VALUES IN(66, 76, 83),
PARTITION technical VALUES IN(65, 69, 71, 73, 84),
PARTITION clerical VALUES IN(75, 78, 89),
PARTITION support VALUES IN(67, 70, 74, 82, 86),
PARTITION unassigned VALUES IN(NULL, 0, 32)
);
表現が分割値リストでは許可されていないため、照合される文字に関してASCIIコードをリストしなければいけません。ASCII(NULL)
が NULL
を返すことに注意してください。
重要もし分割値のリストに含まれないカラム値(もしくはパーティショニング表現が返す値)に行を挿入しようとした場合、INSERT
クエリはエラーを表示し、失敗に終わります。例えば、先ほど概要の説明がされた
LIST
リスト分割スキーマでは、このクエリは失敗します。
INSERT INTO employees VALUES
(224, 'Linus', 'Torvalds', '2002-05-01', '2004-10-12', 'Q', 21);
失敗は、81 (大文字 'Q' ASCII
のアスキーコード)が分割を定義する値のリストに含まれていないためおこります。値のリストに含まれない値を承認する、VALUES
LESS THAN(MAXVALUE) と同義の
分割リストの
「キャッチオール」
定義は存在しません。つまり、照合する全ての値は、値のリスト中に存在していなければいけません。
RANGE
分割と同様に、LIST
分割とキー、ハッシュ分割を合わせることで合成分割を生成できます(サブ分割)。項15.2.5. 「サブ分割」
を参照してください。
