テーブル作成時に、特定の数値列の値が重複せず、かつ連続して増加する必要がある場合、それを自動インクリメント列と呼びます。列の型はAUTO_INCREMENTとして定義でき、これはMySQLテナントの自動インクリメント列に相当します。
自動インクリメント列について
自動インクリメント列のプロパティ
自動インクリメント列には、自動インクリメントの開始値、自動インクリメントのステップサイズ、および自動インクリメント列キャッシュサイズという3つの重要なプロパティがあり、これらは以下の3つのテナント変数パラメータによって制御されます。
| システム変数 | 説明 |
|---|---|
| auto_increment_cache_size | グローバル変数で、自動インクリメントのキャッシュ数を設定します。値の範囲は [1, 100000000] で、デフォルト値は 1000000 です。
説明OceanBaseデータベースでは、テーブル単位で |
| auto_increment_increment | セッション変数で、自動インクリメントのステップサイズを設定します。値の範囲は [1, 65535] で、デフォルト値は 1 です。 |
| auto_increment_offset | セッション変数で、AUTO_INCREMENT 列の値の開始点を決定します。値の範囲は [1, 65535] で、デフォルト値は 1 です。 |
システム変数の設定方法および説明については、構成パラメータとシステム変数の概要を参照してください。
自動インクリメント列のジャンプ
MySQLデータベースでは、自動インクリメント列とはデータベーステーブルにおける列属性の一種であり、その行データを一意に識別するためのユニークかつ連続した値を自動的に生成します。OceanBaseデータベースは分散型データベースであり、そのテーブルは通常複数の異なるマシンに分散配置されています。MySQLデータベースとの互換性を可能な限り保ちつつ、分散アーキテクチャにおける自動インクリメント列の生成性能も確保する必要があるため、自動インクリメント値の生成過程でジャンプ現象が発生することがあります。
OceanBaseデータベースでは、自動インクリメント列には2種類のモードがサポートされており、それぞれNOORDERモードとORDERモードです。デフォルトはORDERモードです。具体的には以下の通りです:
ORDERモード:集中キャッシュに基づく自動インクリメント列です。このモードに設定すると、自動インクリメント列の値はグローバルに連続して増加します。
NOORDERモード:分散キャッシュに基づく自動インクリメント列であり、このモードに設定すると、自動インクリメント列の値がグローバルに一意であることのみが保証されます。
以下では、これら2つのモードについて、それぞれどのように自動インクリメント値の生成過程でジャンプが発生するのかを説明します。
NOORDERモード
OceanBaseデータベースV4.x系では、AUTO_INCREMENT_MODE = 'NOORDER' を指定して作成されたテーブル、およびV4.0.0(このバージョンを除く)以前のバージョンで作成されたすべての自動インクリメント列を含むテーブルは、NOORDERモードの自動インクリメントテーブルとなります。
NOORDERモードの自動インクリメント列について、その内部原理は以下の図のとおりです。

上記の図からわかるように、NOORDERモードの自動インクリメント列のデータ構造は、以下の2つの部分に分かれています:
内部テーブル:現在使用されている自動インクリメント値のポイントを永続化します。
キャッシュ:内部構造に記録された一連の自動インクリメント値の区間であり、内部テーブルから取得します。
NOORDERモードの自動インクリメント列では、各OBServerノード間が独立しており、各ノードは内部テーブルから自動インクリメント区間を取得し、マシンキャッシュに記録することで、自動インクリメント値の生成を高速化できます。以下に、いくつかの典型的なシナリオを例に挙げて、NOORDERモードで自動インクリメント値がジャンプする原因を説明します。
シナリオ1:複数マシン・複数パーティションによる自動インクリメント値の生成
auto_increment_cache_size の値が100と仮定した場合、パーティションテーブルが存在するOBServerノードOBServer1、OBServer2、OBServer3がそれぞれ以下の順序で insert into values (null) のリクエストを受信したとき、それらの内部処理ロジックは次のとおりです:
OBServer1はキャッシュがないことを検出し、内部テーブルから自動インクリメント区間[1,100]を取得し、自動インクリメント値1を生成します。
OBServer2はキャッシュがないことを検出し、内部テーブルから自動インクリメント区間[101,200]を取得し、自動インクリメント値101を生成します。
OBServer3はキャッシュがないことを検出し、内部テーブルから自動インクリメント区間[201,300]を取得し、自動インクリメント値201を生成します。
OBServer1はキャッシュ[2,100]を使用して自動インクリメント値2を生成します。
OBServer2はキャッシュ[102,200]を使用して自動インクリメント値102を生成します。
……
このように、テーブルへのデータ挿入順序は 1、101、201、2、102、... となり、自動インクリメント値は常にジャンプしていることがわかります。
シナリオ2:INSERT ステートメントを使用して指定された最大値を挿入
MySQLデータベースでは、自動インクリメントテーブルに明示的に指定値を挿入すると、その後に生成される自動インクリメント値はすべてその値以上になります。
OceanBaseデータベースの分散シナリオでは、指定値を挿入する際にその値が自動インクリメントテーブル内の他の値よりも大きい(つまり最大値)場合、OBServerノード自身が現在最大値が挿入されたことを認識するだけでなく、他のOBServerノードおよび内部テーブルにも同期する必要があります。この同期アクションは非常に時間がかかるため、毎回最大値を指定するたびに同期操作を実行することを避けるために、システムは最大値を挿入する際に現在のキャッシュを破棄します。これにより、現在の値から次のキャッシュ値までの範囲で同期を行う必要がなくなります。
例えば、パーティションテーブルが存在するOBServer1、OBServer2、OBServer3がそれぞれ以下の順序で明示的に増加シーケンス(1, 2, 3, ...)のリクエストを受信し、これらのマシンにキャッシュが保存されていると仮定した場合:
OBServer1は値1を受信し、キャッシュ[1,100]を破棄し、内部テーブルから新しいキャッシュ区間[301,400]を再取得し、101を同期値として内部テーブルおよび他のOBServerノードに同期します。
OBServer2は値2を受信し、現在のキャッシュ区間[101,200]内の値よりも小さいことを確認し、操作を行いません。
OBServer3は値3を受信し、現在のキャッシュ区間[201,300]内の値よりも小さいことを確認し、操作を行いません。
OBServer1は値4を受信し、現在のキャッシュ区間[301,400]内の値よりも小さいことを確認し、操作を行いません。 ...
このように、一部の値を挿入した後、引き続き自動インクリメント列を使用してシーケンスを生成すると、自動インクリメント値がジャンプします。例えば、OBServer1の最初の区間[1,100]は使用されず、直接301にジャンプします。
複数マシン環境だけでなく、単一マシン環境でも、指定された最大値を挿入すると、自動インクリメント値がジャンプする問題が発生します。例:
自動インクリメント列を含むテーブル
t1を作成します。obclient> CREATE TABLE t1 (c1 int not null auto_increment) AUTO_INCREMENT_MODE='NOORDER';同時に、
auto_increment_cache_sizeの値は100です。このテーブルに複数回データを挿入します。
obclient> INSERT INTO t1 VALUES(null);obclient> INSERT INTO t1 VALUES(3);obclient> INSERT INTO t1 VALUES(null);挿入が成功した後、テーブル内のデータを確認します。
obclient> SELECT * FROM t1;クエリ結果は次のとおりです:
+-----+ | c1 | +-----+ | 1 | | 3 | | 101 | +-----+クエリ結果によると、自動インクリメント列は3から101にジャンプしています。
シナリオ3:マシンの再起動またはダウン
自動インクリメント列のキャッシュはメモリ構造であり、OBServerノードのマシンが再起動またはダウンした場合、そのマシンで使用されていないキャッシュ区間は内部テーブルに書き戻されません。これにより、使用されていないこの部分の区間は再利用されなくなります。例えば、OBServer1上の初期の自動インクリメント列のキャッシュ区間が[1,100]であり、自動インクリメント値1と2が生成されているとします。このとき、OBServer1がダウンした場合、再起動後、そのマシン上のキャッシュ区間は新しい区間[101,200]に変更され、次の自動インクリメント値は101となり、最終的な自動インクリメント値の順序は 1、2、101、... となり、ジャンプが発生します。
ORDERモード
NOORDERモードで述べられているような、複数マシン・複数パーティションにおける自動インクリメント値の生成や**INSERTステートメントを使用して指定された最大値を挿入する**といった一般的な使用シナリオにおいて発生する自動インクリメント値のジャンプ現象を回避するため、OceanBaseデータベースはV4.xバージョンからORDERモードの自動インクリメント列を新たに追加しました。このモードはテーブル作成後のデフォルトモードとなっており、MySQLデータベースとの互換性をより良く保証します。
ORDERモードの自動インクリメント列の内部原理は、以下の図に示されています。

NOORDERモードと比較して、ORDERモードの自動インクリメント列では、すべてのOBServerノードの中から現在のクラスタのリーダーを自動インクリメント列サービスのリーダーとして選択します。他のフォロワーとなるOBServerノードは、リーダーとなるOBServerノードから自動インクリメント値を取得するためにRPCリクエストを送信する必要があります。一方、リーダーとなるOBServerノードは内部テーブルから自動インクリメント区間を取得し、自動インクリメントキャッシュとして利用します。
例えば、同じく複数マシン・複数パーティションのシナリオにおいて、自動インクリメント列のauto_increment_cache_sizeが100であると仮定します。パーティションテーブルが配置されているOBServerノードOBServer1、OBServer2、OBServer3がそれぞれ以下の順序でinsert into values (null)リクエストを受信した場合、それぞれの内部処理ロジックは以下の通りです:
OBServer1は自身がリーダーではないことを検出し、OBServer2にRPCリクエストを送信します。OBServer2は内部テーブルから自動インクリメント区間[1,100]を取得し、OBServer1に自動インクリメント値1を返します。
OBServer2は自身がリーダーであり、かつキャッシュ区間[2,100]が存在することを検出し、直接自動インクリメント値2を生成します。
OBServer3は自身がリーダーではないことを検出し、OBServer2にRPCリクエストを送信します。OBServer2はキャッシュ区間[3,100]が存在することを検出し、OBServer3に自動インクリメント値3を返します。
……
このように、ORDERモードではすべてのOBServerノードがリーダーから自動インクリメント値を取得するため、ほとんどの場合単一マシン環境と同様に、システムは常に連続した自動インクリメント値のシーケンスを生成できます。しかし、同時実行が多い複数マシン環境では、ORDERモードのパフォーマンスはNOORDERモードよりも劣ります。
ORDERモードの自動インクリメント列では、複数マシン・複数パーティションにおける自動インクリメント値の生成や**INSERTステートメントを使用して指定された最大値を挿入する**といったシナリオでの自動インクリメント値のジャンプ現象は解決されましたが、リーダーとなるOBServerノードのマシン再起動やダウン、またはリーダー切り替えが発生した場合、依然として自動インクリメント値のジャンプが発生します。
シナリオ1:マシンの再起動またはダウン
ORDERモードでは、リーダーとなるOBServerノード上にメモリ内のキャッシュ区間が保存されています。リーダーとなるOBServerノードのマシンが再起動またはダウンした場合、その区間内で未使用の自動インクリメント値は引き続き使用されず、新しいキャッシュ区間が使用されるため、自動インクリメント値にジャンプが発生します。
注意
このシナリオでは、リーダーとなるOBServerノードのみが再起動またはダウンした場合にのみ、自動インクリメント値のジャンプ現象が発生します。他のフォロワーとなるOBServerノードはキャッシュを保存していないため、ダウンしても自動インクリメント値の連続性に影響はありません。
シナリオ2:リーダー切り替え
OBServer2上の初期の自動インクリメント列のキャッシュ区間が[1,100]であり、自動インクリメント値1と2が生成されていると仮定します。クラスタ内でリーダー切り替えが発生した場合、通常の処理ロジックに従えば:
リーダーがOBServer1に切り替わり、OBServer1は内部テーブルから新しい自動インクリメント区間[101,200]を取得し、自動インクリメント値101と102を生成し続けます。
OBServer2のマシンが正常に再起動した後、再びOBServer2にリーダーが切り替わり、前回のキャッシュ区間[3,100]を使用して、自動インクリメント値3と4を生成し続けます。
これにより、101から3までの間で自動インクリメント値が増加しない問題が発生していることがわかります。
上記のような往復リーダー切り替えによって引き起こされる自動インクリメント値の増加しない問題を回避するため、OceanBaseデータベースはリーダー切り替え時に元のリーダーとなるOBServerノード上のキャッシュ区間をクリアします。その結果、自動インクリメント値にジャンプが発生します。
自動インクリメント列の作成
テーブル作成時に自動インクリメント列を指定した場合、INSERT ステートメントでレコードを挿入する際にはその列の値を指定する必要がなく、OceanBaseデータベースが自動的にその列に値を代入します。
INSERT 時に自動インクリメント列の値を指定し、かつ SQL_MODE の値が NO_AUTO_VALUE_ON_ZERO に設定されていない場合、指定された値が 0 または現在の最大値よりも大きい場合、OceanBaseデータベースは自動インクリメント列の次の値で列の値を補完します。指定された値が現在の最大値より小さい場合、自動インクリメント列の次の値の計算には影響しません。
説明
SQL_MODE を NO_AUTO_VALUE_ON_ZERO に設定した場合、INSERT で列にゼロを挿入するときに AUTO_INCREMENT を生成しないことを意味します。
t1テーブルを作成し、列制約条件を指定する
obclient> CREATE TABLE t1(id bigint not null auto_increment primary key, name varchar(50), gmt_create timestamp not null default current_timestamp);
Query OK, 0 rows affected
obclient> INSERT INTO t1(name) VALUES('A'),('B'),('C');
Query OK, 3 rows affected
obclient> SELECT * FROM t1;
+----+------+---------------------+
| id | name | gmt_create |
+----+------+---------------------+
| 1 | A | 2020-04-03 17:09:55 |
| 2 | B | 2020-04-03 17:09:55 |
| 3 | C | 2020-04-03 17:09:55 |
+----+------+---------------------+
3 rows in set
例では:
id列のデータ型をbigintと指定します。空値禁止 (
NOT NULL):制約に含まれる列の値がNULLであることを許可しません。auto_increment:自動インクリメント列を設定します。現在、整数型データ型のデータ列 (BOOL/BOOLEAN型を除く) のみが自動インクリメント列に設定できます。primary key:id列を主キー列に設定します。name varchar(50):name列に挿入できるデータ型は文字列型 (varchar) であり、50は最大文字長を表します。id列を自動インクリメント列に設定しているため、INSERTステートメントを使用してレコードを挿入する際には、自動インクリメント列の値を指定する必要はありません。OceanBaseデータベースはこの列に自動的に値を補完します。
t1テーブルにデータを1件挿入し、自動インクリメント列の値を0と指定する
obclient> INSERT INTO t1(id, name) VALUES(0, 'D');
Query OK, 1 row affected
obclient> SELECT * FROM t1;
+----+------+---------------------+
| id | name | gmt_create |
+----+------+---------------------+
| 1 | A | 2021-12-17 14:21:53 |
| 2 | B | 2021-12-17 14:21:53 |
| 3 | C | 2021-12-17 14:21:53 |
| 4 | D | 2021-12-17 14:22:36 |
+----+------+---------------------+
例から分かるように、INSERT 時に自動インクリメント列の値を指定し、その値が 0 である場合、OceanBaseデータベースは自動インクリメント列の次の値で列の値を補完します。
t1テーブルにデータを1件挿入し、自動インクリメント列の値を-1と指定する
obclient> INSERT INTO t1(id, name) VALUES(-1,'E');
Query OK, 1 row affected
obclient> SELECT * FROM t1;
+----+------+---------------------+
| id | name | gmt_create |
+----+------+---------------------+
| -1 | E | 2021-12-17 15:25:04 |
| 1 | A | 2021-12-17 14:21:53 |
| 2 | B | 2021-12-17 14:21:53 |
| 3 | C | 2021-12-17 14:21:53 |
| 4 | D | 2021-12-17 14:22:36 |
+----+------+---------------------+
5 rows in set
例の結果から、-1 は現在の自動インクリメント列の最大値よりも小さいため、自動インクリメント列の次の値の計算に影響を与えないことがわかります。
t1テーブルにデータを1件挿入し、自動インクリメント列の値を10に指定する
obclient> INSERT INTO t1(id, name) VALUES(10,'F');
Query OK, 1 row affected
obclient> SELECT * FROM t1;
+----+------+---------------------+
| id | name | gmt_create |
+----+------+---------------------+
| -1 | E | 2021-12-17 15:25:04 |
| 1 | A | 2021-12-17 14:21:53 |
| 2 | B | 2021-12-17 14:21:53 |
| 3 | C | 2021-12-17 14:21:53 |
| 4 | D | 2021-12-17 14:22:36 |
| 10 | F | 2021-12-17 15:33:28 |
+----+------+---------------------+
6 rows in set
数値10は現在の自動インクリメント列(id列)の最大値(4)よりも大きいため、テーブルt1にname列がGでid列の値を指定しないで再度挿入すると、OceanBaseデータベースは自動的に自動インクリメント列の値10の次の値を使用してid列の値を補完します。
クエリ結果は以下のとおりです:
obclient> INSERT INTO t1(name) VALUES('G');
Query OK, 1 row affected
obclient> SELECT * FROM t1;
+---------+------+---------------------+
| id | name | gmt_create |
+---------+------+---------------------+
| -1 | E | 2020-04-03 17:10:24 |
| 1 | A | 2020-04-03 17:09:55 |
| 2 | B | 2020-04-03 17:09:55 |
| 3 | C | 2020-04-03 17:09:55 |
| 4 | D | 2020-04-03 17:10:19 |
| 10 | F | 2020-04-03 17:10:29 |
| 11 | G | 2020-04-03 17:10:34 |
+---------+------+---------------------+
7 rows in set
通常の列を自動インクリメント列に変更する
OceanBaseデータベースでは、テーブル作成後に、そのテーブル内の通常の列を自動インクリメント列に変更できます。
構文は以下のとおりです:
obclient> ALTER TABLE table_name MODIFY column_name data_type AUTO_INCREMENT;
構文の使用方法:
table_name:変更対象のテーブル名。column_name:自動インクリメント列に変更する列名。data_type:変更対象の列のデータ型。説明
自動インクリメント列に変更する際には、同時にその列のデータ型も変更できますが、変更後のデータ型が自動インクリメントを許可しているデータ型であることを確認する必要があります。
データ型の詳細については、データ型の概要を参照してください。
例:
テーブル
tbl1を作成します。obclient> CREATE TABLE tbl1(id bigint(10));テーブル
tbl1の列を自動インクリメント列に変更します。obclient> ALTER TABLE tbl1 MODIFY id bigint(10) AUTO_INCREMENT;
自動インクリメント列のモードの設定と変更
テーブル作成時に、テーブルレベルパラメータ AUTO_INCREMENT_MODE を使用して自動インクリメント列の自動インクリメントモードを指定することができます。また、テーブル作成後に、その中の自動インクリメント列の自動インクリメントモードを変更することも可能です。さらに、テナントレベルの構成パラメータ default_auto_increment_mode を使用して、テナント内のテーブルの自動インクリメント列のデフォルトの自動インクリメントモードを指定することもできます。
説明
テーブル作成時に自動インクリメントモードが指定されていない場合、テーブル作成後にシステムは構成パラメータの自動インクリメントモードに従って指定します。この構成パラメータのデフォルト値は ORDER です。
例:
テーブル作成時に自動インクリメントモードを指定します。
obclient> CREATE TABLE tbl2(id bigint(10) AUTO_INCREMENT PRIMARY KEY, name varchar(50)) AUTO_INCREMENT_MODE='NOORDER'; Query OK, 0 rows affected obclient> SHOW CREATE TABLE tbl2\G *************************** 1. row *************************** Table: tbl2 Create Table: CREATE TABLE `tbl2` ( `id` bigint(10) NOT NULL AUTO_INCREMENT, `name` varchar(50) DEFAULT NULL, PRIMARY KEY (`id`) ) AUTO_INCREMENT = 1 AUTO_INCREMENT_MODE = 'NOORDER' DEFAULT CHARSET = utf8mb4 ROW_FORMAT = DYNAMIC COMPRESSION = 'zstd_1.3.8' REPLICA_NUM = 1 BLOCK_SIZE = 16384 USE_BLOOM_FILTER = FALSE TABLET_SIZE = 134217728 PCTFREE = 0 1 row in setテーブル作成後に、その中の自動インクリメント列の自動インクリメントモードを変更します。
obclient> CREATE TABLE tbl2(id bigint(10) AUTO_INCREMENT PRIMARY KEY, name varchar(50)); Query OK, 0 rows affected obclient> SHOW CREATE TABLE tbl2\G *************************** 1. row *************************** Table: tbl2 Create Table: CREATE TABLE `tbl2` ( `id` bigint(10) NOT NULL AUTO_INCREMENT, `name` varchar(50) DEFAULT NULL, PRIMARY KEY (`id`) ) AUTO_INCREMENT = 1 AUTO_INCREMENT_MODE = 'ORDER' DEFAULT CHARSET = utf8mb4 ROW_FORMAT = DYNAMIC COMPRESSION = 'zstd_1.3.8' REPLICA_NUM = 1 BLOCK_SIZE = 16384 USE_BLOOM_FILTER = FALSE TABLET_SIZE = 134217728 PCTFREE = 0 1 row in set obclient> ALTER TABLE tbl2 auto_increment_mode = 'NOORDER'; Query OK, 0 rows affected obclient> SHOW CREATE TABLE tbl2\G *************************** 1. row *************************** Table: tbl2 Create Table: CREATE TABLE `tbl2` ( `id` bigint(10) NOT NULL AUTO_INCREMENT, `name` varchar(50) DEFAULT NULL, PRIMARY KEY (`id`) ) AUTO_INCREMENT = 1 AUTO_INCREMENT_MODE = 'NOORDER' DEFAULT CHARSET = utf8mb4 ROW_FORMAT = DYNAMIC COMPRESSION = 'zstd_1.3.8' REPLICA_NUM = 1 BLOCK_SIZE = 16384 USE_BLOOM_FILTER = FALSE TABLET_SIZE = 134217728 PCTFREE = 0 1 row in setパラメータを使用して、テナント内のテーブルの自動インクリメント列のデフォルトの自動インクリメントモードを指定します。
obclient> ALTER SYSTEM SET default_auto_increment_mode = 'ORDER'; Query OK, 0 rows affected obclient> CREATE TABLE tbl3(id bigint(10) AUTO_INCREMENT PRIMARY KEY, name varchar(50)); Query OK, 0 rows affected obclient> SHOW CREATE TABLE tbl3\G *************************** 1. row *************************** Table: tbl3 Create Table: CREATE TABLE `tbl3` ( `id` bigint(10) NOT NULL AUTO_INCREMENT, `name` varchar(50) DEFAULT NULL, PRIMARY KEY (`id`) ) AUTO_INCREMENT = 1 AUTO_INCREMENT_MODE = 'ORDER' DEFAULT CHARSET = utf8mb4 ROW_FORMAT = DYNAMIC COMPRESSION = 'zstd_1.3.8' REPLICA_NUM = 1 BLOCK_SIZE = 16384 USE_BLOOM_FILTER = FALSE TABLET_SIZE = 134217728 PCTFREE = 0 1 row in set
自動インクリメントフィールドの値を変更する
次のSQLステートメントを使用して、テーブル内の自動インクリメント列の次の値を設定できます。値は増加または減少させることができます。
ALTER TABLE table_name AUTO_INCREMENT [=] int_value;
ここで、table_name はテーブル名、int_value はテーブル内の自動インクリメント列の次の値です。
注意
テーブルの自動インクリメントフィールドの値を減らす場合、次の点に注意する必要があります:
テーブルに既存のデータが存在し、自動インクリメント列の最大値が新しく指定された AUTO_INCREMENT 値以上である場合、新しい AUTO_INCREMENT 値は自動的にテーブル内の自動インクリメント列の既存の最大値の次の値に調整されます。例えば、自動インクリメント列の現在の最大値が5で、現在の AUTO_INCREMENT 値が8であり、AUTO_INCREMENT を0から6の間の任意の値に設定した場合、ステートメントの実行が成功した後、実際の AUTO_INCREMENT 値は6に調整されます。
例
以下のSQLステートメントは、テーブルの自動インクリメント列の次の値をどのように調整するかを示しています。
自動インクリメント列の次の値を増やします。
テストテーブル
tbl1を作成します。obclient [test]> CREATE TABLE tbl1(id INT AUTO_INCREMENT, name VARCHAR(50));テーブル
tbl1の現在の自動インクリメントフィールドの値を確認します。obclient [test]> SHOW CREATE TABLE tbl1\G実行結果は次のとおりです:
*************************** 1. row *************************** Table: tbl1 Create Table: CREATE TABLE `tbl1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(50) DEFAULT NULL ) AUTO_INCREMENT = 1 AUTO_INCREMENT_MODE = 'ORDER' DEFAULT CHARSET = utf8mb4 ROW_FORMAT = DYNAMIC COMPRESSION = 'zstd_1.3.8' REPLICA_NUM = 3 BLOCK_SIZE = 16384 USE_BLOOM_FILTER = FALSE TABLET_SIZE = 134217728 PCTFREE = 0 1 row in setテーブル
tbl1に5件のデータを挿入します。obclient [test]> INSERT INTO tbl1(name) VALUES('A1'),('A2'),('A3'),('A4'),('A5');実行結果は次のとおりです:
Query OK, 5 rows affected Records: 5 Duplicates: 0 Warnings: 0再度テーブル
tbl1の現在の自動インクリメントフィールドの値を確認します。obclient [test]> SHOW CREATE TABLE tbl1\G実行結果は次のとおりです:
*************************** 1. row *************************** Table: tbl1 Create Table: CREATE TABLE `tbl1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(50) DEFAULT NULL ) AUTO_INCREMENT = 6 AUTO_INCREMENT_MODE = 'ORDER' DEFAULT CHARSET = utf8mb4 ROW_FORMAT = DYNAMIC COMPRESSION = 'zstd_1.3.8' REPLICA_NUM = 3 BLOCK_SIZE = 16384 USE_BLOOM_FILTER = FALSE TABLET_SIZE = 134217728 PCTFREE = 0 1 row in setテーブル
tbl1の現在の自動インクリメント列の次の値を10に変更します。obclient [test]> ALTER TABLE tbl1 AUTO_INCREMENT = 10;再度テーブル
tbl1の現在の自動インクリメントフィールドの値を確認します。obclient [test]> SHOW CREATE TABLE tbl1\G実行結果は次のとおりです:
*************************** 1. row *************************** Table: tbl1 Create Table: CREATE TABLE `tbl1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(50) DEFAULT NULL ) AUTO_INCREMENT = 10 AUTO_INCREMENT_MODE = 'ORDER' DEFAULT CHARSET = utf8mb4 ROW_FORMAT = DYNAMIC COMPRESSION = 'zstd_1.3.8' REPLICA_NUM = 3 BLOCK_SIZE = 16384 USE_BLOOM_FILTER = FALSE TABLET_SIZE = 134217728 PCTFREE = 0 1 row in set
自動インクリメント列の次の値を減らします。
テーブル
tbl1の現在の自動インクリメント列の次の値を8に変更します。obclient [test]> ALTER TABLE tbl1 AUTO_INCREMENT = 8;テーブル
tbl1の現在の自動インクリメントフィールドの値を確認します。obclient [test]> SHOW CREATE TABLE tbl1\G実行結果は次のとおりです:
*************************** 1. row *************************** Table: tbl1 Create Table: CREATE TABLE `tbl1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(50) DEFAULT NULL ) AUTO_INCREMENT = 8 AUTO_INCREMENT_MODE = 'ORDER' DEFAULT CHARSET = utf8mb4 ROW_FORMAT = DYNAMIC COMPRESSION = 'zstd_1.3.8' REPLICA_NUM = 3 BLOCK_SIZE = 16384 USE_BLOOM_FILTER = FALSE TABLET_SIZE = 134217728 PCTFREE = 0 1 row in setテーブル
tbl1の自動インクリメント列から4以下の値を削除します。obclient [test]> DELETE FROM tbl1 WHERE id <= 4;実行結果は次のとおりです:
Query OK, 4 rows affectedテーブル
tbl1のデータを照会します。obclient [test]> SELECT * FROM tbl1;実行結果は次のとおりです:
+------+------+ | id | name | +------+------+ | 5 | A5 | +------+------+ 1 row in set以下のSQLステートメントを実行して、テーブル
tbl1の現在の自動インクリメント列の次の値を3に変更します。obclient [test]> ALTER TABLE tbl1 AUTO_INCREMENT = 3;実行結果は次のとおりです:
Query OK, 0 rows affected再度テーブル
tbl1の現在の自動インクリメントフィールドの値を確認します。obclient [test]> SHOW CREATE TABLE tbl1\G実行結果は次のとおりです:
*************************** 1. row *************************** Table: tbl1 Create Table: CREATE TABLE `tbl1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(50) DEFAULT NULL ) AUTO_INCREMENT = 6 AUTO_INCREMENT_MODE = 'ORDER' DEFAULT CHARSET = utf8mb4 ROW_FORMAT = DYNAMIC COMPRESSION = 'zstd_1.3.8' REPLICA_NUM = 3 BLOCK_SIZE = 16384 USE_BLOOM_FILTER = FALSE TABLET_SIZE = 134217728 PCTFREE = 0 1 row in set説明
クエリ結果から、
AUTO_INCREMENTの値が6であることがわかります。これは、テーブル内の自動インクリメント列に既にデータが含まれており、現在の自動インクリメント列の最大値(5)が設定しようとしたより小さい値(3)を超えているためです。そのため、自動インクリメント値を減らすコマンドの実行時にエラーは報告されませんでしたが、実際のAUTO_INCREMENT値は既存の最大自動インクリメント値の次の数値、つまり6に自動的に調整されました。