_tidb_rowid
_tidb_rowidはTiDBによって自動的に生成される非表示のシステム列です。クラスタ化インデックスを使用しないテーブルの場合、この列はテーブルの内部行IDとして機能します。テーブルスキーマでこの列を宣言または変更することはできませんが、テーブルが内部行IDとして_tidb_rowid使用している場合は、SQLで参照できます。
現在の実装では、 _tidb_rowidはTiDBによって自動的に管理される追加のBIGINT NOT NULL列です。
_tidb_rowidが利用可能な場合
TiDBでは、テーブルが一意の行識別子としてクラスタ化された主キーを使用しない場合、各行を識別するために_tidb_rowid使用します。実際には、これは次のタイプのテーブルが_tidb_rowid使用することを意味します。
- 主キーのないテーブル
- 主キーが明示的に
NONCLUSTEREDと定義されているテーブル
_tidb_rowidは、クラスター化インデックスを使用するテーブル (つまり、主キーがCLUSTEREDとして定義されているテーブル。主キーが単一列か複合主キーかは関係ありません) では使用できません。
以下の例は、その違いを示しています。
CREATE TABLE t1 (a INT, b VARCHAR(20));
CREATE TABLE t2 (id BIGINT PRIMARY KEY NONCLUSTERED, a INT);
CREATE TABLE t3 (id BIGINT PRIMARY KEY CLUSTERED, a INT);
t1とt2については、これらのテーブルは行識別子としてクラスタ化インデックスを使用していないため、 _tidb_rowidに対してクエリを実行できます。
SELECT _tidb_rowid, a, b FROM t1;
SELECT _tidb_rowid, id, a FROM t2;
t3の場合、クラスタ化された主キーが既に行識別子になっているため、 _tidb_rowid利用できません。
SELECT _tidb_rowid, id, a FROM t3;
ERROR 1054 (42S22): Unknown column '_tidb_rowid' in 'field list'
_tidb_rowidを読み込む
_tidb_rowid使用するテーブルの場合、 SELECTステートメントで_tidb_rowidクエリできます。これは、ページネーション、トラブルシューティング、バッチ処理などのタスクに役立ちます。
例:
CREATE TABLE t (a INT, b VARCHAR(20));
INSERT INTO t VALUES (1, 'x'), (2, 'y');
SELECT _tidb_rowid, a, b FROM t ORDER BY _tidb_rowid;
+-------------+---+---+
| _tidb_rowid | a | b |
+-------------+---+---+
| 1 | 1 | x |
| 2 | 2 | y |
+-------------+---+---+
TiDB が行 ID に割り当てる次の値を表示するには、 SHOW TABLE ... NEXT_ROW_ID使用します。
SHOW TABLE t NEXT_ROW_ID;
+-----------------------+------------+-------------+--------------------+-------------+
| DB_NAME | TABLE_NAME | COLUMN_NAME | NEXT_GLOBAL_ROW_ID | ID_TYPE |
+-----------------------+------------+-------------+--------------------+-------------+
| update_doc_rowid_test | t | _tidb_rowid | 30001 | _TIDB_ROWID |
+-----------------------+------------+-------------+--------------------+-------------+
_tidb_rowidを書き込む
デフォルトでは、TiDB はINSERT 、またはREPLACEステートメントUPDATE _tidb_rowid直接書き込むことを許可しません。
INSERT INTO t(_tidb_rowid, a, b) VALUES (101, 4, 'w');
ERROR 1105 (HY000): insert, update and replace statements for _tidb_rowid are not supported
データインポートまたは移行中に元の行IDを保持する必要がある場合は、まずシステム変数tidb_opt_write_row_id有効にしてください。
SET @@tidb_opt_write_row_id = ON;
INSERT INTO t(_tidb_rowid, a, b) VALUES (100, 3, 'z');
SET @@tidb_opt_write_row_id = OFF;
SELECT _tidb_rowid, a, b FROM t WHERE _tidb_rowid = 100;
+-------------+---+---+
| _tidb_rowid | a | b |
+-------------+---+---+
| 100 | 3 | z |
+-------------+---+---+
制限
_tidb_rowidという名前のユーザー列を作成することはできません。- 既存のユーザー列の名前を
_tidb_rowidに変更することはできません。 _tidb_rowidはTiDBの内部列です。ビジネス上の主キーや長期的な識別子として扱わないでください。- パーティション化された非クラスタ化テーブルでは、
_tidb_rowid値はパーティション間で一意であることが保証されません。3EXCHANGE PARTITION実行した後、異なるパーティションに同じ_tidb_rowid値を持つ行が含まれる可能性があります。 _tidb_rowid存在するかどうかは、テーブルのスキーマによって異なります。クラスタ化インデックスを持つテーブルの場合は、行識別子として主キーを使用してください。
ホットスポットの問題に対処する
_tidb_rowid使用するテーブルの場合、TiDB はデフォルトで行 ID を昇順で割り当てます。書き込み負荷の高いワークロードでは、これにより書き込みホットスポットが発生する可能性があります。
この問題を軽減するために(行IDとして_tidb_rowidを使用するテーブルの場合)、行IDをより均等に分配するためにSHARD_ROW_ID_BITS使用し、必要に応じてリージョンを事前に分割するためにPRE_SPLIT_REGIONS使用することを検討してください。
例:
CREATE TABLE t (
id BIGINT PRIMARY KEY NONCLUSTERED,
c INT
) SHARD_ROW_ID_BITS = 4;
SHARD_ROW_ID_BITS _tidb_rowid使用するテーブルにのみ適用され、クラスター化インデックスを持つテーブルには適用されません。
関連する記述と変数
SHOW TABLE NEXT_ROW_ID:TiDBが次に割り当てる行IDを示しますSHARD_ROW_ID_BITS:ホットスポットを減らすために暗黙の行IDをシャーディングするClustered Indexes: テーブルが主キーを使用する理由を説明します_tidb_rowidtidb_opt_write_row_id:_tidb_rowidへの書き込みを許可するかどうかを制御します