MySQL AUTO_INCREMENT と例
⚡ スマートサマリー
MySQL AUTO_INCREMENT属性は、数値列に新しい行が挿入されるたびに、自動的に連番を生成します。この属性により、一意の識別子を手動で計算する必要がなくなるため、主キーを設定する標準的な方法となっています。

自動インクリメントとは何ですか?
自動インクリメントは、数値データ型を操作する関数です。自動インクリメントとして定義されたフィールドのテーブルにレコードが挿入されるたびに、連続した数値が自動的に生成されます。
この属性は、TINYINTからBIGINTまでのあらゆる整数型に対応しています。また、列にはインデックスが設定されている必要があり、これは主キーとして宣言すると自動的に行われます。
自動インクリメントを使用する場合?
レッスンでは データベース正規化そこで、主キーと外部キーを使って互いに関連付けられた多数の小さなテーブルにデータを格納することで、冗長性を最小限に抑えてデータを保存する方法について検討しました。
主キーはデータベース内の行を一意に識別するため、一意でなければなりません。では、主キーが常に一意であることをどのように保証できるのでしょうか?
考えられる解決策の一つは、主キーを生成する数式を使用し、データを追加する前にテーブル内にキーが存在するかどうかを確認することです。この方法は有効かもしれませんが、複雑で万全ではありません。同時に挿入しようとする2つのセッションが同じ最大値を読み取り、衝突する可能性があります。
このような複雑さを回避し、主キーが常に一意であることを保証するために、 MySQL 主キーを生成するための自動インクリメント機能。自動インクリメントはINTデータ型で使用されます。INTデータ型は符号付き値と符号なし値の両方をサポートします。符号なしデータ型には正の数のみが含まれます。ベストプラクティスとして、自動インクリメント主キーに符号なし制約を定義することをお勧めします。
自動インクリメント構文
論理的な説明がまとまったので、映画カテゴリ表を作成するために使用されたスクリプトを見てみましょう。
CREATE TABLE `categories` ( `category_id` int UNSIGNED NOT NULL AUTO_INCREMENT, `category_name` varchar(150) DEFAULT NULL, `remarks` varchar(500) DEFAULT NULL, PRIMARY KEY (`category_id`) );
category_id フィールドに「AUTO_INCREMENT」が付いていることに注目してください。これにより、テーブルに新しい行が挿入されるたびに、カテゴリ ID が自動的に生成されます。テーブルにデータを挿入する際には、この値は指定されません。 MySQL それを生成します。
注意: UNSIGNEDキーワードは列の正の範囲を2倍にし、かつてint(11)として記述されていた表示幅は非推奨になりました。 MySQL 8.0.17以降。プレーン int型 これが現在の形式です。
デフォルトでは、AUTO_INCREMENT の初期値は 1 であり、新しいレコードが追加されるたびに 1 ずつ増加します。
カテゴリ表の現在の内容を確認してみましょう。
SELECT * FROM `categories`;
上記のスクリプトを実行すると、 MySQL myflixdb に対して Workbench を実行すると、以下の結果が得られます。
| category_id | category_name | remarks |
|---|---|---|
| 1 | Comedy | Movies with humour |
| 2 | Romantic | Love stories |
| 3 | Epic | Story acient movies |
| 4 | Horror | NULL |
| 5 | Science Fiction | NULL |
| 6 | Thriller | NULL |
| 7 | Action | NULL |
| 8 | Romantic Comedy | NULL |
8行存在するので、次に生成されるIDは9になります。それでは、カテゴリテーブルに新しいカテゴリを挿入し、名前だけを指定してみましょう。
INSERT INTO `categories` (`category_name`) VALUES ('Cartoons');
上記のスクリプトを myflixdb に対して実行します。 MySQL 作業台 以下に示す結果が得られます。
| category_id | category_name | remarks |
|---|---|---|
| 1 | Comedy | Movies with humour |
| 2 | Romantic | Love stories |
| 3 | Epic | Story acient movies |
| 4 | Horror | NULL |
| 5 | Science Fiction | NULL |
| 6 | Thriller | NULL |
| 7 | Action | NULL |
| 8 | Romantic Comedy | NULL |
| 9 | Cartoons | NULL |
なお、カテゴリIDは提供しておりません。 MySQL カテゴリIDが自動インクリメントとして定義されているため、自動的に生成されました。
によって生成された最後の挿入 ID を取得したい場合は、 MySQL、LAST_INSERT_ID 関数を使用してこれを行うことができます。以下に示すスクリプトは、生成された最後の ID を取得します。
SELECT LAST_INSERT_ID();
上記のスクリプトを実行すると、INSERTクエリによって生成された最後の自動インクリメント番号が取得されます。結果は以下のとおりです。
ヒント: LAST_INSERT_ID() は自身の接続にのみ適用されるため、他のユーザーの挿入によって生成された値が誤って返されることはありません。
AUTO_INCREMENTの開始値を設定またはリセットする方法
デフォルトのシーケンスは1から始まりますが、プロジェクトによっては必ずしもそれが適切とは限りません。請求書番号は既存システムから引き継ぐ必要がある場合があり、テストテーブルをリセットする必要が生じることもよくあります。 MySQL カウンターを直接公開することで、どちらの場合も単一の句で処理できます。開始番号を制御するには、以下の手順に従ってください。
- 作成時に値を設定します。 CREATE TABLE文にAUTO_INCREMENT句を追加します。そうすると、最初に挿入される行には1の代わりにその番号が割り当てられます。
- 既存のテーブルの値を変更します。 他の机 同じ条項で。 MySQL 新しい番号は、現在保存されている最大の識別子よりも大きい場合にのみ受け入れられます。
- 空にしたテーブルをリセットします。 TRUNCATE TABLEは、すべての行を削除し、カウンターを1に戻すという一連の操作を1回で実行しますが、DELETE単独ではそれができません。
- 変更を確認します。 新しいシーケンスに依存する前に、行を挿入し、LAST_INSERT_ID() を使用して識別子を読み戻してください。
-- Start a brand-new table at 1000 CREATE TABLE `invoices` ( `invoice_id` int UNSIGNED NOT NULL AUTO_INCREMENT, `amount` decimal(10,2), PRIMARY KEY (`invoice_id`) ) AUTO_INCREMENT = 1000; -- Move the counter on an existing table ALTER TABLE `categories` AUTO_INCREMENT = 100; -- Empty the table and reset the counter to 1 TRUNCATE TABLE `categories`;
ステップサイズは、auto_increment_increment システム変数でも変更できますが、これは単一のテーブルではなくサーバー全体に適用されます。主にレプリケーションで使用され、2 つのサーバーが同じ識別子を生成しないようにする必要があります。
AUTO_INCREMENTシーケンスにギャップが生じるのはなぜですか?
遅かれ早かれ、テーブルには1、2、5、6といった識別子が表示されます。これは何も問題ではありません。カウンターは一意性を保証するように設計されており、連続した数値を保証するようには設計されておらず、同じ値を二度出力することはありません。
ギャップが生じる理由は以下のとおりです。
- 削除された行: テーブルから行が削除された場合、その行に自動的に割り当てられたIDは再利用されません。 MySQL 順次新しい数字を生成し続けます。
- ロールバックされたトランザクション: 番号は挿入処理が実行された瞬間に取得されます。トランザクションがロールバックされた場合、行は削除されますが、番号は既に使用済みとなります。
- 挿入失敗: UNIQUE制約によって拒否されたステートメントでも、失敗する前に識別子を消費してしまう可能性があります。
- バルク挿入物: InnoDBは、複数行挿入のために数値のブロックを予約し、使用しない数値は破棄する場合があります。
これらのギャップを埋めようとするのは間違いです。行番号を振り直すと、それらを指すすべての外部キーが壊れてしまい、値自体にはビジネス上の意味がありません。レポートで連続したリストが必要な場合は、保存されているデータを書き換えるのではなく、クエリで行番号を生成してください。

