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のように扱われることを簡単に確認できます。