AUTO_RANDOMv3.1.0の新機能
ノート:
AUTO_RANDOMは、v4.0.3以降安定しているとマークされています。
ユーザーシナリオ
データをTiDBに集中的に書き込む場合、TiDBに自動インクリメント整数型の主キーを持つテーブルがあると、ホットスポットの問題が発生する可能性があります。ホットスポットの問題を解決するには、 AUTO_RANDOM属性を使用できます。
詳細については、 非常に同時の書き込みのベストプラクティスを参照してください。
例として、次の作成されたテーブルを取り上げます。
CREATE TABLE t (a bigint PRIMARY KEY AUTO_INCREMENT, b varchar(255))
このtのテーブルで、次のように主キーの値を指定しないINSERTのステートメントを多数実行します。
INSERT INTO t(b) VALUES ('a'), ('b'), ('c')
上記のステートメントでは、主キー(列a )の値が指定されていないため、TiDBは行IDとして連続自動インクリメント行値を使用します。これにより、単一のTiKVノードで書き込みホットスポットが発生し、パフォーマンスに影響を与える可能性があります。このような書き込みホットスポットを回避するために、テーブルの作成時に列aのAUTO_INCREMENT属性ではなくAUTO_RANDOM属性を指定できます。次の例を参照してください。
CREATE TABLE t (a bigint PRIMARY KEY AUTO_RANDOM, b varchar(255))
また
CREATE TABLE t (a bigint AUTO_RANDOM, b varchar(255), PRIMARY KEY (a))
次に、 INSERT INTO t(b) VALUES...などのINSERTステートメントを実行します。これで、結果は次のようになります。
- 値の暗黙的な割り当て:
INSERTステートメントが整数主キー列(列a)の値を指定しない場合、または値をNULLとして指定しない場合、TiDBはこの列に値を自動的に割り当てます。これらの値は、必ずしも自動インクリメントまたは連続である必要はありませんが、一意であるため、連続行IDによって引き起こされるホットスポットの問題を回避できます。 - 値の明示的な挿入:
INSERTステートメントが整数主キー列の値を明示的に指定する場合、TiDBはこれらの値を保存します。これは、AUTO_INCREMENT属性と同様に機能します。@@sql_modeシステム変数にNO_AUTO_VALUE_ON_ZEROを設定しない場合、整数主キー列の値を0として明示的に指定しても、TiDBはこの列に値を自動的に割り当てることに注意してください。
ノート:
v4.0.3以降、値を明示的に挿入する場合は、
@@allow_auto_random_explicit_insertシステム変数の値を1(デフォルトでは0)に設定します。この明示的な挿入はデフォルトではサポートされておらず、その理由は制限セクションに記載されています。
TiDBは、次の方法で値を自動的に割り当てます。
バイナリ(つまり、シャードビット)の行値の上位5桁(符号ビットを無視)は、現在のトランザクションの開始時刻によって決定されます。残りの桁には、自動インクリメント順に値が割り当てられます。
異なる数のシャードビットを使用するには、 AUTO_RANDOMに括弧のペアを追加し、括弧内に必要な数のシャードビットを指定します。次の例を参照してください。
CREATE TABLE t (a bigint PRIMARY KEY AUTO_RANDOM(3), b varchar(255))
上記のCREATE TABLEのステートメントでは、 3のシャードビットが指定されています。シャードビット数の範囲は[1, 16)です。
テーブルを作成した後、 SHOW WARNINGSステートメントを使用して、現在のテーブルでサポートされている暗黙的な割り当ての最大数を確認します。
SHOW WARNINGS
+-------+------+----------------------------------------------------------+
| Level | Code | Message |
+-------+------+----------------------------------------------------------+
| Note | 1105 | Available implicit allocation times: 1152921504606846976 |
+-------+------+----------------------------------------------------------+
ノート:
v4.0.3以降、
AUTO_RANDOM列のタイプはBIGINTのみになります。これは、暗黙的な割り当ての最大数を確保するためです。
さらに、 AUTO_RANDOM属性を持つテーブルのシャードビット番号を表示するには、 information_schema.tablesシステムテーブルのTIDB_ROW_ID_SHARDING_INFO列にPK_AUTO_RANDOM_BITS=xモードの値を表示できます。 xはシャードビットの数です。
AUTO_RANDOM列に割り当てられた値はlast_insert_id()に影響します。 SELECT last_insert_id ()を使用して、TiDBが最後に暗黙的に割り当てるIDを取得できます。例えば:
INSERT INTO t (b) VALUES ("b")
SELECT * FROM t;
SELECT last_insert_id()
次の結果が表示される場合があります。
+------------+---+
| a | b |
+------------+---+
| 1073741825 | b |
+------------+---+
+------------------+
| last_insert_id() |
+------------------+
| 1073741825 |
+------------------+
互換性
TiDBは、バージョンコメント構文の解析をサポートしています。次の例を参照してください。
CREATE TABLE t (a bigint PRIMARY KEY /*T![auto_rand] auto_random */)
CREATE TABLE t (a bigint PRIMARY KEY AUTO_RANDOM)
上記の2つのステートメントは同じ意味です。
SHOW CREATE TABLEの結果では、 AUTO_RANDOM属性がコメント化されています。このコメントには、属性識別子(たとえば、 /*T![auto_rand] auto_random */ )が含まれます。ここで、 auto_randはAUTO_RANDOM属性を表します。この識別子に対応する機能を実装するバージョンのTiDBのみが、SQLステートメントフラグメントを適切に解析できます。
この属性は、上位互換性、つまりダウングレード互換性をサポートします。この機能を実装していない以前のバージョンのTiDBは、テーブルのAUTO_RANDOM属性(上記のコメント付き)を無視し、その属性でテーブルを使用することもできます。
制限
AUTO_RANDOMを使用する場合は、次の制限に注意してください。
- この属性は、整数型の主キー列にのみ指定してください。そうしないと、エラーが発生する可能性があります。また、主キーの属性が
NONCLUSTEREDの場合、整数の主キーでもAUTO_RANDOMはサポートされません。CLUSTEREDタイプの主キーの詳細については、 クラスター化されたインデックスを参照してください。 ALTER TABLEを使用して、この属性の追加または削除を含め、AUTO_RANDOM属性を変更することはできません。AUTO_RANDOM属性で指定された主キー列の列タイプは変更できません。- 同じ列に
AUTO_RANDOMとAUTO_INCREMENTを同時に指定することはできません。 - 同じ列に
AUTO_RANDOMとDEFAULT(列のデフォルト値)を同時に指定することはできません。 - データを挿入するときに、
AUTO_RANDOM属性を持つ列の値を明示的に指定することはお勧めしません。そうしないと、このテーブルに自動的に割り当てられる数値が事前に使い果たされる可能性があります。