今日は新人エンジニアのみなさんからよく相談される「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の一意性と不可変性」の原則を学ぼう
  • TRUNCATEDELETEの違いを理解しよう
  • PreparedStatementなど、JavaからのSQL実行方法をマスターしよう
  • 本番環境で使える安全なデータ削除・リセットの運用パターンを考えてみよう

データの「ID」はとても大事な要素です。今後はID管理のベストプラクティスもどんどん身につけていきましょう!

最後までお読みいただきありがとうございます。