5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

[小ネタ] MySQLのAUTO_INCREMENTは勝手にテーブルのデータの最大値から始まる

Last updated at Posted at 2022-12-07

MySQL の AUTO_INCREMENT

突然ですが、MySQLには他DBMSにあるシーケンスという種類のオブジェクトはありません。 マニュアルを探しても本当にありません。

その代わりテーブルのカラムに AUTO_INCREMENT を指定してテーブル固有の勝手に増えるIDを実現することが可能です。下記が例です。

CREATE TABLE `hogehoge` (
  `id` bigint unsigned NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`id`)
);
INSERT INTO hogehoge VALUES ();
INSERT INTO hogehoge VALUES ();
INSERT INTO hogehoge VALUES ();

-- => 3
SELECT MAX(id) FROM hogehoge;

AUTO_INCREMENTはコンフリクトするか?

ここで、本題ですが、前述の状態の id = 3 まで進んだテーブルの定義(DDL)をバックアップすると下記のようなDDLを mysqldump 氏が作成してくれます。

CREATE TABLE `hogehoge` (
  `id` bigint unsigned NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`id`)
) AUTO_INCREMENT=4;

AUTO_INCREMENT=4 でシーケンスを初期値 4 にしてくれているようですね。この状態で新規INSERTすると 4 からINSERTされます。

INSERT INTO hogehoge VALUES ();

-- => 4
SELECT MAX(id) FROM hogehoge;

ただ、システムバックアップあるあるですが、バックアップ取得の際に、1. 上記のバックアップDDL発行と 2. バックアップDML(INSERT文)の取得の発行のタイミングが異なると、上記の AUTO_INCREMENT=4 に反して、下記のようなバックアップが取得されてしまいます。

INSERT INTO hogehoge VALUES (1);
INSERT INTO hogehoge VALUES (2);
INSERT INTO hogehoge VALUES (3);
INSERT INTO hogehoge VALUES (4); -- あっ……
INSERT INTO hogehoge VALUES (5); -- あっ!

どうやら、DDLからDMLのバックアップの隙間に新規データが2件挿入されたようですね。

「これってテーブル側のシーケンスが =4 の状態なのに、次にINSERTでコンフリクトするじゃん!」

と思ってしまいますが、そこはMySQL、 ちゃんとテーブルの最大値の次に大きい値を採番して勝手に回避してくれます

試しに大きな値(100)を挿入して

INSERT INTO hogehoge VALUES (100);

-- => 100
SELECT MAX(id) FROM hogehoge;

再び自動採番させてみれば 101 が来るので、MySQLが勝手にテーブルの最大値を参照してINSERTのコンフリクトを回避していることが分かります。

INSERT INTO hogehoge VALUES ();

-- => 101
SELECT MAX(id) FROM hogehoge;

AUTO_INCREMENT は過去に戻るか?

逆に 100 101 を消して再度、 INSERT するとどうなるのでしょうか?

DELETE FROM hogehoge WHERE id >= 100;

INSERT INTO hogehoge VALUES ();

-- => 102
SELECT MAX(id) FROM hogehoge;

一度進んだシーケンスは戻りません。 まあ戻ったりしたら、DELETEしたデータを戻した際にコンフリクトするので妥当な仕様でしょう。

まとめ

  • AUTO_INCREMENT は勝手にテーブルのデータの最大値から始まり、コンフリクトしない
  • 一度進んだシーケンスは戻らない
5
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?