10bet网址
MySQL 5.6リファレンスマニュアル
下载本手册
PDF(美国高级主任)- 26.8 mb
PDF (A4)- 26.8 mb


19.2.7 MySQLパティショニングによるNULLの扱い

MySQLのパーティショニングには,パーティショニング式の値(カラム値またはユーザー定義式の値にかかわらず)としてを拒否する手段はありません。式の値としてを使用することは許可されていますが(そうでない場合は整数を返す必要がある),は数値でないことを認識することは重要です。MySQLのパティショニング実装は,命令のように,でない値より小さい値としてを扱います。

これは,の扱いは各タイプのパーティショニングで異なり,これに準備していない場合は予期しない動作になる可能性があることを意味します。このような状況があるので,このセクションでは,各MySQLパーティショニングタイプが,行をどのパーティションに格納するべきかを判断するときに値をどのように扱うかを説明し,それぞれの例を示します。

范围パ,ティショニングでのnullの扱いパ,ティションを判断するために使用されるカラム値がである行を,范围によってパーティション化されたテーブルに挿入した場合,行はもっとも低いパーティションに挿入されます。pという名前のデタベスに,次のように作成された2のテブルがあるとします。

mysql> CREATE TABLE t1 (-> c1 INT, -> c2 VARCHAR(20) -> PARTITION BY RANGE(c1) (-> PARTITION p0 VALUES LESS THAN (0), -> PARTITION p1 VALUES LESS THAN (10), -> PARTITION p2 VALUES LESS THAN MAXVALUE ->);查询OK, 0 rows affected (0.09 sec) mysql> CREATE TABLE t2 (- > c1 INT, -> c2 VARCHAR(20) ->) -> PARTITION BY RANGE(c1) (- > PARTITION p0 VALUES LESS THAN (-5), -> PARTITION p1 VALUES LESS THAN (0), -> PARTITION p2 VALUES LESS THAN (10), -> PARTITION p3 VALUES LESS THAN MAXVALUE ->);查询OK, 0行受影响(0.09秒)

これらの2の创建表ステトメントによって作成されたパティションにいては,次のクエリをINFORMATION_SCHEMAデ,タベ,ス内の分区テ,ブルに対して使用することで確認できます。

mysql> SELECT TABLE_NAME, PARTITION_NAME, TABLE_ROWS, AVG_ROW_LENGTH, DATA_LENGTHWHERE TABLE_SCHEMA = 'p' AND TABLE_NAME LIKE 't_';+------------+----------------+------------+----------------+-------------+ | TABLE_NAME | PARTITION_NAME | TABLE_ROWS | AVG_ROW_LENGTH | DATA_LENGTH  | +------------+----------------+------------+----------------+-------------+ | t1 | p0 | 0 | 0 | 0 | | t1 | p1 | 0 | 0 | 0 | | t1 | p2 | 0 | 0 | 0 | | t2 | p0 | 0 | 0 | 0 | | t2 | p1 | 0 | 0 | 0 | | t2 | p2 | 0 | 0 | 0 | | t2 | p3 | 0 | 0 | 0  | +------------+----------------+------------+----------------+-------------+ 7行集(0.00秒)

(このテブルにいての詳細は,セクション21.13 " information_schema partitionsテブル"を参照してください.)ここで,これらの各テ,ブルのパ,ティショニングキ,として使用されるカラムにが含まれる単一行を移入し,2の选择ステ,トメントを使用してこれらの行が挿入されたことを確認します。

mysql> INSERT INTO t1 VALUES (NULL, 'mothra');mysql> INSERT INTO t2 VALUES (NULL, 'mothra');mysql> SELECT * FROM t1;+------+--------+ | id |名称  | +------+--------+ | 零|摩斯拉也  | +------+--------+ 1行组(0.00秒)mysql >选择从t2 *;+------+--------+ | id |名称  | +------+--------+ | 零|摩斯拉也  | +------+--------+ 1行集(0.00秒)

挿入された行を格納するためにどのパティションが使用されたかにいては,前のクエリをINFORMATION_SCHEMA。分区に対して再実行して出力を検査することで確認できます。

mysql> SELECT TABLE_NAME, PARTITION_NAME, TABLE_ROWS, AVG_ROW_LENGTH, DATA_LENGTHWHERE TABLE_SCHEMA = 'p' AND TABLE_NAME LIKE 't_';+------------+----------------+------------+----------------+-------------+ | TABLE_NAME | PARTITION_NAME | TABLE_ROWS | AVG_ROW_LENGTH | DATA_LENGTH  | +------------+----------------+------------+----------------+-------------+| t1 | p0 | 1 | 20 | 20 || t1 | p1 | 0 | 0 | 0 | | t1 | p2 | 0 | 0 | 0 || t2 | p0 | 1 | 20 | 20 || t2 | p1 | 0 | 0 | 0 | | t2 | p2 | 0 | 0 | 0 | | t2 | p3 | 0 | 0 | 0  | +------------+----------------+------------+----------------+-------------+ 7行集(0.01秒)

これらの行が各テーブルのもっとも低いパーティションに格納されたことについては,これらのパーティションを削除してから选择ステ,トメントを再実行することで確認できます。

ALTER TABLE t1 DROP PARTITION p0mysql> ALTER TABLE t2 DROP PARTITION p0mysql> SELECT * FROM t1;mysql> SELECT * FROM t2;空集(0.00秒)

修改表…删除分区の詳細にいては,セクション13.1.7 " alter table構文"を参照してください。)

SQL関数を使用するパティショニング式の場合も,はこのように扱われます。次のような创建表ステ,トメントを使用してテ,ブルを定義するとします。

CREATE TABLE tndate (id INT, dt DATE) PARTITION BY RANGE(年份)(分区p0值小于(1990),分区p1值小于(2000),分区p2值小于MAXVALUE);

ほかのMySQL関数と同様に,(空)を返します。dtカラム値がである行は,パ,ティショニング式がほかの値より小さい値に評価されたかのように扱われ,パ,ティションp0に挿入されます。

列表パ,ティショニングでの,空の扱い列表によってパ,ティション化されたテ,ブルで値が許可されるのは,が含まれている値リストを使用していずれかのパ,ティションが定義されている場合のみです。これとは逆に,列表によってパ,ティション化されたテ,ブルが,値リストでを明示的に使用していない場合は,次の例のようにパ,ティショニング式で値に評価される行を拒否します。

mysql> CREATE TABLE ts1 (-> c1 INT, -> c2 VARCHAR(20) ->) -> PARTITION BY LIST(c1) (-> PARTITION p0 VALUES IN (0,3,6), -> PARTITION p1 VALUES IN (1,4,7), -> PARTITION p2 VALUES IN (2,5,8) ->);mysql> INSERT INTO ts1 VALUES (9, 'mothra');错误1504 (HY000): mysql> INSERT INTO ts1 VALUES (NULL, 'mothra');错误1504 (HY000):表没有NULL值的分区

壹空间に挿入できるのは,c1値が0以上8以下の行のみです。は,数値9と同様にこの範囲を外れます。が含まれる値リストを持テブルts2およびts3は次のように作成できます。

mysql> CREATE TABLE ts2 (-> c1 INT, -> c2 VARCHAR(20) ->) -> PARTITION BY LIST(c1) (-> PARTITION p0 VALUES IN (0,3,6), -> PARTITION p1 VALUES IN (1,4,7), -> PARTITION p2 VALUES IN (2,5,8), -> PARTITION p3 VALUES IN (NULL) ->);查询OK, 0 rows affected(0.01秒)mysql> CREATE TABLE ts3 (-> c1 INT, -> c2 VARCHAR(20) ->) -> PARTITION BY LIST(c1) (-> PARTITION p0 VALUES IN (0,3,6), -> PARTITION p1 VALUES IN (1,4,7, NULL), -> PARTITION p2 VALUES IN (2,5,8) ->);查询OK, 0行受影响(0.01秒)

パ,ティショニングの値リストを定義するときに,をほかの値と同様に扱うことができます(そうすべきです)。たとえば,(null)中的值および(1,4,7, null)中的值は両方とも有効であり,(1, null, 4,7)中的值(null, 1,4,7)中的值なども同様です。カラムc1である行をテ,ブルts2およびts3にそれぞれ挿入できます。

INSERT INTO ts2 VALUES (NULL, 'mothra');mysql> INSERT INTO ts3 VALUES (NULL, 'mothra');查询确定,影响1行(0.00秒)

INFORMATION_SCHEMA。分区に対して適切なクエリーを発行することによって,先ほど挿入した行を格納するためにどのパーティションが使用されたかを確認できます(前の例と同様に,パーティション化されたテーブルがpデ,タベ,スに作成されたことを想定しています)。

mysql> SELECT TABLE_NAME, PARTITION_NAME, TABLE_ROWS, AVG_ROW_LENGTH, DATA_LENGTHWHERE TABLE_SCHEMA = 'p' AND TABLE_NAME LIKE 'ts_';+------------+----------------+------------+----------------+-------------+ | TABLE_NAME | PARTITION_NAME | TABLE_ROWS | AVG_ROW_LENGTH | DATA_LENGTH  | +------------+----------------+------------+----------------+-------------+ | ts2 | p0 | 0 | 0 | 0 | | ts2 | p1 | 0 | 0 | 0 | | ts2 | p2 | 0 | 0 | 0 || ts2 | p3 | 1 | 20 | 20 || ts3 | p0 | 0 | 0 | 0 || ts3 | p1 | 1 | 20 | 20 || ts3 | p2 | 0 | 0 | 0  | +------------+----------------+------------+----------------+-------------+ 7行集(0.01秒)

このセクションですでに示したように,行を格納するためにどのパーティションが使用されたかについては,それらのパーティションを削除してから选择を実行することで確認できます。

Hashおよびkeyパ,ティショニングでのnullの扱い哈希または关键によってパ,ティション化されたテ,ブルの場合,の扱いは少し異なります。これらの場合,値を返すパ,ティショニング式は,戻り値がゼロであったかのように扱われます。この動作にいては,哈希によってパーティション化されたテーブルを作成して該当する値が含まれるレコードを挿入することで,ファイルシステムにどのような影響があるかを検査することで確認できます。次のステ,トメントを使用して作成されたテ,ブルth(これも)pデ,タベ,ス内)があるとします。

mysql> CREATE TABLE th (-> c1 INT, -> c2 VARCHAR(20) -> PARTITION BY HASH(c1) -> PARTITIONS 2;查询OK, 0行受影响(0.00秒)

このテ,ブルに属するパ,ティションは,次のクエリ,を使用して表示できます。

mysql> SELECT TABLE_NAME,PARTITION_NAME,TABLE_ROWS,AVG_ROW_LENGTH,DATA_LENGTHWHERE TABLE_SCHEMA =' p' AND TABLE_NAME ='th';+------------+----------------+------------+----------------+-------------+ | TABLE_NAME | PARTITION_NAME | TABLE_ROWS | AVG_ROW_LENGTH | DATA_LENGTH  | +------------+----------------+------------+----------------+-------------+ | th | p0 | 0 | 0 | 0 | | | p1 | 0 | 0 | 0  | +------------+----------------+------------+----------------+-------------+ 2行集(0.00秒)

各パ,ティションのTABLE_ROWSは0です。ここで次に示すように,c1カラム値がおよび0である2の行をthに挿入し,それらの行が挿入されたことを確認します。

mysql> INSERT INTO th VALUES (NULL, 'mothra'), (0, 'gigan');mysql> SELECT * FROM th (0.00 sec)+------+---------+ | c1 | c2  | +------+---------+ | 零|摩斯拉也  | +------+---------+ | 0 | gigan  | +------+---------+ 2行集(0.01秒)

任意の整数Nにいて,零模Nの値は常にであることを思い出してください。哈希または关键によってパ,ティション化されたテ,ブルの場合,この結果は正しいパ,ティションを判別するために0として扱われます。INFORMATION_SCHEMA。分区テ,ブルを再度確認すると,両方の行がパ,ティションp0に挿入されたことがわかります。

mysql> SELECT TABLE_NAME, PARTITION_NAME, TABLE_ROWS, AVG_ROW_LENGTH, DATA_LENGTHWHERE TABLE_SCHEMA =' p' AND TABLE_NAME ='th';+------------+----------------+------------+----------------+-------------+ | TABLE_NAME | PARTITION_NAME | TABLE_ROWS | AVG_ROW_LENGTH | DATA_LENGTH  | +------------+----------------+------------+----------------+-------------+| th | p0 | 2 | 20 | 20 || | p1 | 0 | 0 | 0  | +------------+----------------+------------+----------------+-------------+ 2行集(0.00秒)

テ,ブルの定義で按哈希分区の代わりに按键分区を使用してこの例を繰り返すと,このタが0のように扱われることを簡単に確認できます。