Documentation Home
MySQL 8.0 リファレンスマニュアル
Download this Manual
PDF (US Ltr) - 36.1Mb
PDF (A4) - 36.2Mb


このページは機械翻訳したものです。

24.2.3.1 RANGE COLUMNS パーティショニング

RANGE COLUMNS パーティショニングは RANGE パーティショニングに似ていますが、複数のカラム値に基づく範囲を使用してパーティションを定義できます。 また、整数型以外の型のカラムを使用して範囲を定義できます。

RANGE COLUMNS パーティショニングは、次の点で RANGE パーティショニングと大きく異なります。

  • RANGE COLUMNS は式を受け入れません (カラムの名前のみ)。

  • RANGE COLUMNS は 1 つ以上のカラムのリストを受け入れます。

    RANGE COLUMNS パーティションは、スカラー値の比較ではなく、タプル (カラム値のリスト) の比較に基づきます。 RANGE COLUMNS パーティションでの行の配置も、タプルの比較に基づきます。これについては、このセクションで後述します。

  • RANGE COLUMNS パーティショニングカラムは整数カラムに制限されません。文字列、DATE、および DATETIME カラムもパーティショニングカラムとして使用できます。 (詳細は、セクション24.2.3「COLUMNS パーティショニング」を参照してください。)

RANGE COLUMNS によってパーティション化されたテーブルを作成するための基本構文を次に示します。

CREATE TABLE table_name
PARTITIONED BY RANGE COLUMNS(column_list) (
    PARTITION partition_name VALUES LESS THAN (value_list)[,
    PARTITION partition_name VALUES LESS THAN (value_list)][,
    ...]
)

column_list:
    column_name[, column_name][, ...]

value_list:
    value[, value][, ...]
注記

パーティション化されたテーブルを作成するときに使用できる CREATE TABLE オプションをすべて示しているわけではありません。 詳細は、セクション13.1.20「CREATE TABLE ステートメント」を参照してください。

前述の構文で、column_list は 1 つ以上のカラムのリスト (パーティショニングカラムリストと呼ばれることもあります)、value_list は値のリスト (つまり、パーティション定義値リストです) です。 value_list は各パーティション定義に指定する必要があり、各 value_list には column_list のカラムと同じ数の値が必要です。 一般的に、COLUMNS 句に N 個のカラムを使用する場合は、各 VALUES LESS THAN 句にも N 個の値のリストを指定する必要があります。

パーティショニングカラムリストおよび各パーティションを定義する値リスト内の要素は、同じ順序で指定する必要があります。 また、値リスト内の各要素は、カラムリスト内の対応する要素と同じデータ型である必要があります。 ただし、パーティショニングカラムリストおよび値リスト内のカラム名の順序は、CREATE TABLE ステートメントの主要部内のテーブルカラム定義の順序と同じである必要はありません。 RANGE によってパーティション化されるテーブルと同様に、MAXVALUE を使用して、指定されたカラムに挿入される正当な値より確実に大きな値を表すことができます。 これらの点をすべて説明するために役立つ CREATE TABLE ステートメントの例を次に示します。

mysql> CREATE TABLE rcx (
    ->     a INT,
    ->     b INT,
    ->     c CHAR(3),
    ->     d INT
    -> )
    -> PARTITION BY RANGE COLUMNS(a,d,c) (
    ->     PARTITION p0 VALUES LESS THAN (5,10,'ggg'),
    ->     PARTITION p1 VALUES LESS THAN (10,20,'mmm'),
    ->     PARTITION p2 VALUES LESS THAN (15,30,'sss'),
    ->     PARTITION p3 VALUES LESS THAN (MAXVALUE,MAXVALUE,MAXVALUE)
    -> );
Query OK, 0 rows affected (0.15 sec)

テーブル rcx にはカラム abc、および d が含まれています。 COLUMNS 句に指定されたパーティショニングカラムリストには、これらのカラムのうちの 3 つが ad、および c の順に使用されています。 パーティションを定義するために使用される各値リストには、同じ順序で 3 つの値が含まれます。つまり、各値リストタプルの形式は、カラム ad、および c が (この順序で) 使用するデータ型に対応する、(INT, INT, CHAR(3)) です。

パーティションに行がどのように配置されるかは、挿入される行のタプル (COLUMNS 句内のカラムリストに一致) とVALUES LESS THAN 句に使用されるタプル (テーブルのパーティションを定義) を比較することによって判断されます。 スカラー値ではなくタプル (つまり、値のリストまたはセット) を比較するため、RANGE COLUMNS パーティションで使用される VALUES LESS THAN のセマンティクスは、単純な RANGE パーティションの場合とは若干異なります。 RANGE パーティショニングでは、VALUES LESS THAN 内の制限値と等しい式値を生成する行は、対応するパーティションに配置されません。ただし、RANGE COLUMNS パーティショニングを使用するときは、パーティショニングカラムリストの最初の要素が VALUES LESS THAN 値リスト内の最初の要素と値が等しい行が、対応するパーティションに配置されることがあります。

次のステートメントによって作成されるパーティション化された RANGE テーブルを検討します。

CREATE TABLE r1 (
    a INT,
    b INT
)
PARTITION BY RANGE (a)  (
    PARTITION p0 VALUES LESS THAN (5),
    PARTITION p1 VALUES LESS THAN (MAXVALUE)
);

各行の a のカラム値が 5 である 3 つの行をこのテーブルに挿入する場合、各行の a カラム値が 5 以上であるため、3 行がすべてパーティション p1 に格納されます。これは、INFORMATION_SCHEMA.PARTITIONS テーブルに対して適切なクエリーを実行することによって確認できます。

mysql> INSERT INTO r1 VALUES (5,10), (5,11), (5,12);
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> SELECT PARTITION_NAME,TABLE_ROWS
    ->     FROM INFORMATION_SCHEMA.PARTITIONS
    ->     WHERE TABLE_NAME = 'r1';
+----------------+------------+
| PARTITION_NAME | TABLE_ROWS |
+----------------+------------+
| p0             |          0 |
| p1             |          3 |
+----------------+------------+
2 rows in set (0.00 sec)

ここで、次のように作成される、カラム a および b の両方が COLUMNS 句で参照される、RANGE COLUMNS パーティショニングを使用する同様のテーブル rc1 を検討します。

CREATE TABLE rc1 (
    a INT,
    b INT
)
PARTITION BY RANGE COLUMNS(a, b) (
    PARTITION p0 VALUES LESS THAN (5, 12),
    PARTITION p3 VALUES LESS THAN (MAXVALUE, MAXVALUE)
);

r1 に挿入したのとまったく同じ行を rc1 に挿入した場合、行の配分はかなり異なります。

mysql> INSERT INTO rc1 VALUES (5,10), (5,11), (5,12);
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> SELECT PARTITION_NAME,TABLE_ROWS
    ->     FROM INFORMATION_SCHEMA.PARTITIONS
    ->     WHERE TABLE_NAME = 'rc1';
+--------------+----------------+------------+
| TABLE_SCHEMA | PARTITION_NAME | TABLE_ROWS |
+--------------+----------------+------------+
| p            | p0             |          2 |
| p            | p1             |          1 |
+--------------+----------------+------------+
2 rows in set (0.00 sec)

これは、スカラー値ではなく行を比較しているためです。 挿入された行値と、テーブル rc1 のパーティション p0 を定義するために使用された VALUES THAN LESS THAN 句の行制限値とを次のように比較できます。

mysql> SELECT (5,10) < (5,12), (5,11) < (5,12), (5,12) < (5,12);
+-----------------+-----------------+-----------------+
| (5,10) < (5,12) | (5,11) < (5,12) | (5,12) < (5,12) |
+-----------------+-----------------+-----------------+
|               1 |               1 |               0 |
+-----------------+-----------------+-----------------+
1 row in set (0.00 sec)

2 つのタプル (5,10) および (5,11)(5,12) より小さいと評価されるため、パーティション p0 に格納されています。 5 は 5 以上、12 は 12 以上であるため、(5,12)(5,12) 以上と見なされ、パーティション p1 に格納されています。

前の例の SELECT ステートメントは、次のように明示的な行コンストラクタを使用して記述することもできました。

SELECT ROW(5,10) < ROW(5,12), ROW(5,11) < ROW(5,12), ROW(5,12) < ROW(5,12);

MySQL で行コンストラクタを使用する方法についての詳細は、セクション13.2.11.5「行サブクエリー」を参照してください。

単一パーティショニングカラムのみを使用して RANGE COLUMNS によってパーティション化されたテーブルの場合、パーティションへの行の格納は RANGE によってパーティション化された同等のテーブルの場合と同じです。 次の CREATE TABLE ステートメントでは、1 つのパーティショニングカラムを使用して RANGE COLUMNS によってパーティション化されるテーブルが作成されます。

CREATE TABLE rx (
    a INT,
    b INT
)
PARTITION BY RANGE COLUMNS (a)  (
    PARTITION p0 VALUES LESS THAN (5),
    PARTITION p1 VALUES LESS THAN (MAXVALUE)
);

このテーブルに行 (5,10)(5,11)、および (5,12) を挿入する場合、それらの配置は、前に作成して移入したテーブル r の場合と同じです。

mysql> INSERT INTO rx VALUES (5,10), (5,11), (5,12);
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> SELECT PARTITION_NAME,TABLE_ROWS
    ->     FROM INFORMATION_SCHEMA.PARTITIONS
    ->     WHERE TABLE_NAME = 'rx';
+--------------+----------------+------------+
| TABLE_SCHEMA | PARTITION_NAME | TABLE_ROWS |
+--------------+----------------+------------+
| p            | p0             |          0 |
| p            | p1             |          3 |
+--------------+----------------+------------+
2 rows in set (0.00 sec)

1 つ以上のカラムの制限値が連続するパーティション定義で繰り返される、RANGE COLUMNS によってパーティション化されるテーブルを作成することもできます。 これを行うには、パーティションを定義するために使用されるカラム値のタプルが厳密にしだいに増加する必要があります。 たとえば、次の各 CREATE TABLE ステートメントは有効です。

CREATE TABLE rc2 (
    a INT,
    b INT
)
PARTITION BY RANGE COLUMNS(a,b) (
    PARTITION p0 VALUES LESS THAN (0,10),
    PARTITION p1 VALUES LESS THAN (10,20),
    PARTITION p2 VALUES LESS THAN (10,30),
    PARTITION p3 VALUES LESS THAN (MAXVALUE,MAXVALUE)
 );

CREATE TABLE rc3 (
    a INT,
    b INT
)
PARTITION BY RANGE COLUMNS(a,b) (
    PARTITION p0 VALUES LESS THAN (0,10),
    PARTITION p1 VALUES LESS THAN (10,20),
    PARTITION p2 VALUES LESS THAN (10,30),
    PARTITION p3 VALUES LESS THAN (10,35),
    PARTITION p4 VALUES LESS THAN (20,40),
    PARTITION p5 VALUES LESS THAN (MAXVALUE,MAXVALUE)
 );

次のステートメントも成功しますが、カラム b の制限値がパーティション p0 で 25 およびパーティション p1 で 20、カラム c の制限値がパーティション p1 で 100 およびパーティション p2 で 50 であるため、一見したところではそうでないように見えるかもしれません。

CREATE TABLE rc4 (
    a INT,
    b INT,
    c INT
)
PARTITION BY RANGE COLUMNS(a,b,c) (
    PARTITION p0 VALUES LESS THAN (0,25,50),
    PARTITION p1 VALUES LESS THAN (10,20,100),
    PARTITION p2 VALUES LESS THAN (10,30,50)
    PARTITION p3 VALUES LESS THAN (MAXVALUE,MAXVALUE,MAXVALUE)
 );

RANGE COLUMNS によってパーティション化されるテーブルを設計するときは、次のように mysql クライアントを使用して目的のタプルを比較することで、いつでも連続するパーティション定義をテストできます。

mysql> SELECT (0,25,50) < (10,20,100), (10,20,100) < (10,30,50);
+-------------------------+--------------------------+
| (0,25,50) < (10,20,100) | (10,20,100) < (10,30,50) |
+-------------------------+--------------------------+
|                       1 |                        1 |
+-------------------------+--------------------------+
1 row in set (0.00 sec)

CREATE TABLE ステートメントに含まれるパーティション定義が、厳密にしだいに増加しない順序である場合は、次の例に示すようにエラーで失敗します。

mysql> CREATE TABLE rcf (
    ->     a INT,
    ->     b INT,
    ->     c INT
    -> )
    -> PARTITION BY RANGE COLUMNS(a,b,c) (
    ->     PARTITION p0 VALUES LESS THAN (0,25,50),
    ->     PARTITION p1 VALUES LESS THAN (20,20,100),
    ->     PARTITION p2 VALUES LESS THAN (10,30,50),
    ->     PARTITION p3 VALUES LESS THAN (MAXVALUE,MAXVALUE,MAXVALUE)
    ->  );
ERROR 1493 (HY000): VALUES LESS THAN value must be strictly increasing for each partition

そのようなエラーが発生するときは、それらのカラムリストの小なり比較を作成することで、無効なパーティション定義を推定できます。 この場合、問題はパーティション p2 の定義にあります。次に示すように、それを定義するために使用されるタプルが、パーティション p3 を定義するために使用されるタプル以上であるためです。

mysql> SELECT (0,25,50) < (20,20,100), (20,20,100) < (10,30,50);
+-------------------------+--------------------------+
| (0,25,50) < (20,20,100) | (20,20,100) < (10,30,50) |
+-------------------------+--------------------------+
|                       1 |                        0 |
+-------------------------+--------------------------+
1 row in set (0.00 sec)

RANGE COLUMNS を使用するときは、複数の VALUES LESS THAN 句内の同じカラムに MAXVALUE を指定することもできます。 ただし、それ以外の場合は、連続するパーティション定義内の個々のカラムの制限値はしだいに増加するべきであり、MAXVALUE をすべてのカラム値の上限として使用するパーティションは 1 つだけ定義するべきであり、このパーティション定義は PARTITION ... VALUES LESS THAN 句のリストの最後に指定するべきです。 また、複数のパーティション定義の最初のカラムの制限値として MAXVALUE を使用することはできません。

前述したように、RANGE COLUMNS パーティショニングでは、整数以外のカラムをパーティショニングカラムとして使用することもできます (これらの完全な一覧については、セクション24.2.3「COLUMNS パーティショニング」を参照してください)。 次のステートメントを使用して作成された employees という名前のテーブル (パーティション化されていません) を検討します。

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 NOT NULL,
    store_id INT NOT NULL
);

RANGE COLUMNS パーティショニングを使用して、次のように従業員の姓に基づいて各行を 4 つのパーティションのいずれかに格納する、このテーブルのバージョンを作成できます。

CREATE TABLE employees_by_lname (
    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 NOT NULL,
    store_id INT NOT NULL
)
PARTITION BY RANGE COLUMNS (lname)  (
    PARTITION p0 VALUES LESS THAN ('g'),
    PARTITION p1 VALUES LESS THAN ('m'),
    PARTITION p2 VALUES LESS THAN ('t'),
    PARTITION p3 VALUES LESS THAN (MAXVALUE)
);

または、次の ALTER TABLE ステートメントを実行することで、前に作成した employees テーブルをこのスキームを使用してパーティション化できます。

ALTER TABLE employees PARTITION BY RANGE COLUMNS (lname)  (
    PARTITION p0 VALUES LESS THAN ('g'),
    PARTITION p1 VALUES LESS THAN ('m'),
    PARTITION p2 VALUES LESS THAN ('t'),
    PARTITION p3 VALUES LESS THAN (MAXVALUE)
);
注記

文字セットおよび照合順序が異なるとソート順序が異なるため、文字列カラムをパーティショニングカラムとして使用するときに、使用している文字セットおよび照合順序が、指定された行が RANGE COLUMNS によってパーティション化されるテーブルのどのパーティションに格納されるかに影響することがあります。 また、そのようなテーブルが作成されたあとに指定されたデータベース、テーブル、またはカラムの文字セットまたは照合順序を変更すると、行がどのように配分されるかが変わることがあります。 たとえば、大/小文字を区別する照合を使用する場合、'and''Andersen'の前にソートしますが、大/小文字を区別しない照合を使用する場合、その逆が当てはまります。

MySQL が文字セットおよび照合順序をどのように扱うかについては、第10章「文字セット、照合順序、Unicodeを参照してください。

同様に、employees テーブルを、各行がいくつかの 10 年間 (その間に対応する従業員が雇用された) ベースのパーティションのいずれかに格納されるように、次のような ALTER TABLE ステートメントを使用してパーティション化できます。

ALTER TABLE employees PARTITION BY RANGE COLUMNS (hired)  (
    PARTITION p0 VALUES LESS THAN ('1970-01-01'),
    PARTITION p1 VALUES LESS THAN ('1980-01-01'),
    PARTITION p2 VALUES LESS THAN ('1990-01-01'),
    PARTITION p3 VALUES LESS THAN ('2000-01-01'),
    PARTITION p4 VALUES LESS THAN ('2010-01-01'),
    PARTITION p5 VALUES LESS THAN (MAXVALUE)
);

PARTITION BY RANGE COLUMNS 構文の詳細については、セクション13.1.20「CREATE TABLE ステートメント」を参照してください。