STR_HASH は、PolarDB-X 1.0 向けのパーティション関数であり、文字列型のパーティションキーを持つデータを単一のデータベースシャードまたはテーブルシャードにルーティングします。この関数は、パーティションキー値から位置または長さに基づいて部分文字列を抽出し、その部分文字列を用いて対象シャードを計算します。
STR_HASH はポイントクエリのみをサポートします。パーティションキーに対する範囲クエリは単一のシャードにルーティングされず、全表スキャンをトリガーするため、応答時間が遅くなります。
制限事項
パーティションキー列のデータ型は
CHARまたはVARCHARである必要があります。テーブル作成後に STR_HASH のパラメーターを変更することはできません。
PolarDB-X 1.0 インスタンスのバージョンは 5.3.5 以降である必要があります。
構文
STR_HASH( shardKey [, startIndex, endIndex [, valType [, randSeed ] ] ] )パラメーター
| パラメーター | 説明 | デフォルト |
|---|---|---|
shardKey | パーティションキー列名。 | — |
startIndex | 部分文字列の開始位置(0 基準)。最後の endIndex 文字を使用する場合は -1 を指定します。 | -1 |
endIndex | 部分文字列の終了位置(0 基準、排他的)。先頭の startIndex 文字を使用する場合は -1 を指定します。 | -1 |
valType | ルーティングにおける部分文字列の解釈方法:0 = 文字列ハッシュ、1 = 整数。 | 0 |
randSeed | valType=0 の場合に文字列ハッシュで使用されるランダムシードです。データ分布が不均等な場合にのみ変更してください。デフォルト値は 31 であり、その他の有効な値には 131、13131、1313131 があります。 | 31 |
部分文字列の抽出ルール
startIndex および endIndex パラメーターは、パーティションキー値のどの部分をルーティングに使用するかを制御します。
| 条件 | 抽出される部分文字列 |
|---|---|
startIndex=j、endIndex=k(j≥0、k≥0、k>j) | 元の文字列の範囲 [j, k) の文字 |
startIndex=-1、endIndex=k(k≥0) | 末尾の k 文字。文字列の長さが k より短い場合は、文字列全体が使用されます。 |
startIndex=k、endIndex=-1(k≥0) | 先頭の k 文字。文字列の長さが k より短い場合は、文字列全体が使用されます。 |
startIndex=-1、endIndex=-1 | 切り捨てなし — 文字列全体が使用されます。 |
ABCDEFG を用いた例:
| 式 | 結果 |
|---|---|
[1, 5) | BCDE |
[2, 2) | ''(空) |
[4, 100) | EFG |
[100, 105) | ''(空) |
valType の値
0(デフォルト): PolarDB-X 1.0 は部分文字列を文字列として扱い、ハッシュ関数を適用してシャードを計算します。1: PolarDB-X 1.0 は部分文字列を整数として扱ってシャードを計算します。整数値は9223372036854775807を超えてはならず、浮動小数点数であってはなりません。
randSeed は valType=0 の場合にのみ適用されます。テーブル作成後に randSeed を変更した場合、すべてのデータをエクスポートし、新しいパーティショニングアルゴリズムを用いて再インポートすることで、データを正しく再分散する必要があります。
適用範囲/利用シーン
STR_HASH は、注文 ID やユーザー ID などの文字列型列をパーティションキーとし、アクセスパターンの大部分がポイントクエリであるシナリオ向けに設計されています。たとえば、ID を用いたトランザクションや物流注文の検索などが該当します。
STR_HASH による正確なルーティングが実現されるケース:
デフォルトの HASH 関数では、文字列値全体のハッシュを計算するため、複数の異なる値が同一のシャードにマップされる可能性があります。一方、STR_HASH を使用すると、注文 ID の末尾 3 桁など、既知の数値部分文字列を抽出し、それを整数として扱うことで、各異なる部分文字列値が必ず 1 つのシャードにのみマップされることが保証されます。
例:インターネット金融アプリケーションこのアプリケーションでは、YYYYMM を用いてデータをデータベースシャードに年月単位でパーティション化し、さらに注文 ID でテーブルシャードに分割します。各注文 ID の末尾 3 文字は 000~999 の範囲の整数です。要件として、各異なる 3 桁のサフィックス値が物理テーブルシャードに 1 対 1 でマップされる必要があります。
-- ルーティング:int(order_id[-3:]) % 1024 → サフィックス値ごとに 1 つの物理テーブルシャード
CREATE TABLE test_str_hash_tb (
id INT NOT NULL AUTO_INCREMENT,
order_id VARCHAR(30) NOT NULL,
create_time DATETIME DEFAULT NULL,
PRIMARY KEY(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
DBPARTITION BY YYYYMM(`create_time`)
TBPARTITION BY STR_HASH(`order_id`, -1, 3, 1) TBPARTITIONS 1024;1,024 個のテーブルシャードと 1,000 個の異なるサフィックス値(000~999)がある場合、各サフィックス値は必ず 1 つのシャードにのみルーティングされます。デフォルトの HASH 関数では、この保証が得られません。なぜなら、ハッシュ値が複数の異なる文字列値を同一の整数にマップし、1 つのシャードが複数のサフィックス値に対応することになるためです。
例
以下の例では、パーティションキーとして order_id VARCHAR(32) を持つテーブルを使用し、4 つのデータベースシャードおよび 8 つのテーブルシャード(4 つのデータベース × 各データベースに 2 つのテーブル)にパーティション化しています。
末尾 4 文字を整数としてルーティングに使用:
-- ルーティング:int(order_id[-4:]) % 4 → データベースシャード;% 2 → テーブルシャード
CREATE TABLE test_str_hash_tb (
id INT NOT NULL AUTO_INCREMENT,
order_id VARCHAR(32) NOT NULL,
create_time DATETIME DEFAULT NULL,
PRIMARY KEY(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
DBPARTITION BY STR_HASH(`order_id`, -1, 4, 1)
TBPARTITION BY STR_HASH(`order_id`, -1, 4, 1) TBPARTITIONS 2;位置 2~6(3 文字目~7 文字目)の文字列をルーティングに使用:
-- ルーティング:hash(order_id[2:7]) % 4 → データベースシャード;% 2 → テーブルシャード
CREATE TABLE test_str_hash_tb (
id INT NOT NULL AUTO_INCREMENT,
order_id VARCHAR(32) NOT NULL,
create_time DATETIME DEFAULT NULL,
PRIMARY KEY(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
DBPARTITION BY STR_HASH(`order_id`, 2, 7)
TBPARTITION BY STR_HASH(`order_id`, 2, 7) TBPARTITIONS 2;先頭 5 文字を文字列としてルーティングに使用:
-- ルーティング:hash(order_id[:5]) % 4 → データベースシャード;% 2 → テーブルシャード
CREATE TABLE test_str_hash_tb (
id INT NOT NULL AUTO_INCREMENT,
order_id VARCHAR(32) NOT NULL,
create_time DATETIME DEFAULT NULL,
PRIMARY KEY(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
DBPARTITION BY STR_HASH(`order_id`, 5, -1)
TBPARTITION BY STR_HASH(`order_id`, 5, -1) TBPARTITIONS 2;よくある質問
STR_HASH(order_id) と HASH(order_id) の違いは何ですか?
両関数とも文字列型列をパーティションキーとして使用し、ハッシュ値を計算して対象シャードを決定します。主な違いは以下のとおりです:
STR_HASH ではハッシュ計算前に部分文字列を抽出できるため、注文 ID の末尾 4 桁など、キー値の既知のセグメントをターゲットにできます。
STR_HASH は文字列ベースのルーティングに UNI_HASH アルゴリズムを使用します。一方、HASH は文字列全体のハッシュに対して単純な剰余演算を実行します。
valType=1の場合、STR_HASH は部分文字列を整数として扱い、決定論的にルーティングします。つまり、各異なる整数値は必ず 1 つのシャードにマップされます。HASH ではこのような保証はありません。
既知の部分文字列値とシャードとの間に 1 対 1 の正確なルーティングが必要な場合は STR_HASH を使用してください。部分文字列の抽出が不要な汎用的な文字列パーティショニングには HASH を使用します。