今日は新人エンジニアのみなさんからよく相談される「AUTO_INCREMENTの連番が歯抜けになっちゃった問題」について、優しく解説していきます!
「DELETEとINSERTを繰り返してたら、idの番号が飛んでるんですけど…」
…そんな経験ありませんか?
これ、MySQLあるあるなんです。でも心配いりません。ちゃんと意味があって、対処法もあります。
AUTO_INCREMENTとは?
まず、基本から確認しましょう。
AUTO_INCREMENT(オートインクリメント)とは、MySQLで主に使われる「自動で連番を振る仕組み」です。
テーブルを定義するときにこう書くと…
id INT AUTO_INCREMENT PRIMARY KEY
新しいレコードをINSERTするたびに、idが「1、2、3…」と自動で増えていきます。
まるで受付番号の札を順番に配るようなものですね!
なぜ連番が飛ぶの?
例:IDが「1, 2, 4」になってしまうケース
たとえば、こんな操作をしたとしましょう。
INSERT INTO cars (name) VALUES ('Toyota'); -- id = 1
INSERT INTO cars (name) VALUES ('Nissan'); -- id = 2
DELETE FROM cars WHERE id = 2;
INSERT INTO cars (name) VALUES ('Honda'); -- id = 3(でも2は使われない!)
「2を消したんだから、次は2を使ってくれればいいのに!」
…と思うかもしれませんが、MySQLはそういう仕組みにはなっていません。
理由は?
- 安全性のため:一度使ったIDは再利用しないのが基本
- IDは一意(ユニーク)な識別子であり、「消したから番号戻す」は推奨されない
歯抜けをリセットするには?
方法①:全レコード削除後にリセット(TRUNCATE TABLE)
全データを消して、連番も1からに戻したいなら、次のSQLが便利です。
TRUNCATE TABLE cars;
これは単なる全削除(DELETE FROM
)と違って、AUTO_INCREMENTもリセットされます。
ただし、
- すべてのデータが完全に消える
- ロールバックができない
という特徴があるため、開発用やテスト用DBでのみ使いましょう!
方法②:特定の番号にリセットする(ALTER TABLE)
「1〜8番はもう使った。次は9番から始めたい!」
というケースでは、次のSQLを使います。
ALTER TABLE cars AUTO_INCREMENT = 9;
これで次にINSERTしたレコードのIDが「9」から始まるようになります。
❗ 注意:この方法では「過去に削除した番号を埋める」ことはできません!
方法③:IDを明示的に指定して埋める
途中の番号(たとえばID=3)を明示的に使いたいなら、こうします。
INSERT INTO cars (id, name) VALUES (3, 'Mazda');
ただし、すでにそのIDが存在していたらエラーになりますし、AUTO_INCREMENTの値は更新されません。
実運用でリセットしてもいいの?
基本的に、本番環境ではAUTO_INCREMENTのリセットはおすすめしません。
なぜなら…
- 削除されたIDを再利用するとデータが衝突するリスクがある
- ログや履歴とIDがずれる可能性がある
- 外部参照(外部キー)との整合性が崩れることがある
IDは一度発行されたら変更しないというのが、データベース設計のセオリーです。
JavaからAUTO_INCREMENTをリセットするサンプル
業務でJava + MySQLを使っている方のために、参考コードも紹介します。
public class AutoIncrement extends SuperDao {
private PreparedStatement ps;
public void ResetAutoIncrement(String tableName) {
this.connect();
String SQL = "ALTER TABLE " + tableName + " AUTO_INCREMENT = 1";
try {
ps = con.prepareStatement(SQL);
ps.executeUpdate();
} catch (SQLException e) {
System.err.println(e);
} finally {
this.close();
}
System.out.println(tableName + "のauto_incrementの連番をリセットしました。");
}
public static void main(String[] args) {
AutoIncrement autoIncrement = new AutoIncrement();
autoIncrement.ResetAutoIncrement("cars");
}
}
このように、Javaからも連番リセットは実行可能です。
まとめ
- AUTO_INCREMENTは連番を自動で振る仕組み
- DELETEやROLLBACKで番号は飛ぶが、それは仕様
- どうしてもリセットしたいなら TRUNCATE か ALTER TABLE
- ただし、実運用では注意!ID再利用はトラブルのもと
今後の学習の指針
- データベース設計における「IDの一意性と不可変性」の原則を学ぼう
TRUNCATE
とDELETE
の違いを理解しようPreparedStatement
など、JavaからのSQL実行方法をマスターしよう- 本番環境で使える安全なデータ削除・リセットの運用パターンを考えてみよう
データの「ID」はとても大事な要素です。今後はID管理のベストプラクティスもどんどん身につけていきましょう!