HASH
によるパーティショニングは前もって決められた数のパーティショニングの中でデータを均等に割り振るために使用されます。
レンジやリストパーティショニングでは、どのパーティションにカラム値やカラム値のセットが記憶されるか特定しなければいけません。ハッシュパーティショニングでは、MySQLがこれを自動的に実行してくれるため、ハッシュされるカラム値に対してカラム値や表現と、パーティショニングされたテーブルのパーティションの数だけ特定すれば事足ります。
HASH
パーティショニングを使用してテーブルをパーティショニングする場合、CREATE
TABLE
ステートメントに PARTITION BY
HASH (
節を付加する必要があります。この時、expr
)expr
は整数を返す表現です。これは単純に、MySQLの整数タイプと同様のタイプのカラムの名前でけっこうです。加えて、PARTITIONS
節で続かせるのが定石です。この時、num
num
はパーティショニングされたテーブルのパーティションの数を表現するネガティブ値ではない整数になります。
例えば、以下のステートメントは
store_id
カラムに対してハッシングを行い、4つのパーティションに分かれるテーブルを作成します。
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 HASH(store_id) PARTITIONS 4;
PARTITIONS
節を含めない場合、パーティションの数はデフォルトで
1
となります。
PARTITIONS
キーワードの続きに数字が使用されていない場合、構文エラーとなります。
expr
に対して整数を返すSQL表現を使用することもできます。例えば、雇用年度に対してパーティショニングを行いたいとします。以下のようにできます。
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 HASH( YEAR(hired) ) PARTITIONS 4;
非定数、非ランダム整数値を返すという条件をクリアしていれば、MySQLで有効な
expr
に対してどの関数でも表現でも使用することができます。(言い換えれば、多様性があっても、断言的でなければいけません。)ただし、行が挿入もしくは更新(削除)されるたび、この表現が評価されます。これは、特に多数の行に影響を及ぼすオペレーション(例えばバッチ挿入)を実行する際、きわめて複雑な表現はパフォーマンス問題を浮上させる可能性があります。
最も効率的なハッシュ関数では、単一のテーブルカラムに対して実行され、その値がカラム値に比例して増大、減少します。これにより、パーティションのレンジを 「pruning」 することができます。つまり、表現が基となるカラムの値に対して比例すればするほど、MySQLはその表現をハッシュパーティショニングにその分だけ効率よく用いることができます。
たとえば、date_col
が
DATE
のカラム型である場合、表現
TO_DAYS(date_col)
は
date_col
の値に対して直接比例します。これは
date_col
の値が変更されるたびに、表現の値が一定の割合で変更されるからです。YEAR(date_col)
表現の date_col
に対する変化は、TO_DAYS(date_col)
に対する変化と比べて直接的ではありません。これは、date_col
内の変化の全てが YEAR(date_col)
に対して同等の変更を促すとは限らないからです。それでも、YEAR(date_col)
はハッシュ関数の優れた候補となります。date_col
の一部と直接比例する上、date_col
内には YEAR(date_col)
に対して不均衡な変化を促すものが無いからです。
逆に、INT
型を持つ
int_col
というカラムがあるとします。この表現
POW(5-int_col,3) + 6
を検討してください。これはハッシュ関数に使用するには優れた候補とはいえません。なぜなら、int_col
の値に変化がおきた時、値の表現に対して比例する変化が起きる保証がないからです。int_col
の値を変更すれば、表現の値にもさまざまな変化を促します。例えば
int_col
を 5
から
6
に変えると、表現の値に
-1
という変化をもたらしますが、int_col
の値を 6
から 7
に変えると、表現の値に -7
という変化をもたらします。
言い換えると、, グラフのカラム値に対して
versus 表現の値が
y=
この時
n
xn
は 0
以外の定数という条件のもと直線をなぞるほど、その表現はハッシュにふさわしいものになります。これは、表現が非直線状的であればあるほど、パーティション内で割り振られるデータが不均衡になりがちであることと関係しています。
セオリーでは、「刈り込み」は1つ以上のカラム値を含む表現にも使用できますが、ふさわしい表現の特定は難しい上に、多くの時間を要します。このため、複数のカラムに対してハッシュ表現を使用することは推奨できません。
PARTITION BY HASH
が使用される時 MySQL は num
どのパーティションが使用されるかを、ユーザ関数の結果係数に基づいて断定します。言い換えれば、expr
の表現に対して、レコードが記憶されたパーティションの番号は
N
であり、
.例えば、テーブル
N
=
MOD(expr
,
num
)
となります。t1
が以下の様に定義され、4のパーティションがあるとします。
CREATE TABLE t1 (col1 INT, col2 CHAR(5), col3 DATE) PARTITION BY HASH( YEAR(col3) ) PARTITIONS 4;
t1
にレコードを挿入し、col3
値が
'2005-09-15'
の場合、それが記憶されるパーティションは以下の様に断定されます。
MOD(YEAR('2005-09-01'),4) = MOD(2005,4) = 1
MySQL 5.1 は HASH
パーティショニングの変形である、linear
hashing
もサポートしており、これはパーティショニングされたテーブルに新しい行を配置する際にさらに複雑なアルゴリズムを使用します。詳細については、
項15.2.3.1. 「LINEAR HASH
パーティショニング」
を参照してください。
レコードが挿入もしくは更新されるたびに、ユーザ関数は評価されます。それは — 状況によって、— レコードが消去される際に評価されることもあります。
注:パーティショニングされるテーブルに
UNIQUE
キーがある場合、HASH
ユーザ関数や KEY
の
column_list
に対してアーギュメントとして提供されたカラムは、そのキーの一部出なければいけません。例外:この制限は
NDBCluster
記憶エンジンを使用しているテーブルには当てはまりません。