MySQL AUTO_INCREMENT と例

⚡ スマートサマリー

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

  • 🔢 コア行動: AUTO_INCREMENT は、新しい行が挿入されるたびに、1 から始まり、ステップ 1 で次の番号を発行します。ping 1によります。
  • 🔑 主要な役割: この属性は、検索クエリなしで一意の識別子を保証するため、代理主キーの標準的な選択肢となっています。
  • 🧱 列の要件: その列は整数型である必要があり、インデックスが付けられている必要があります。PRIMARY KEY宣言は既にこの条件を満たしています。
  • パターンを挿入する: INSERT ステートメントから識別子列を省略し、 MySQL 値を指定すると、LAST_INSERT_ID() がその値を返します。
  • 🎚️ カスタム開始値: CREATE TABLE または ALTER TABLE では、AUTO_INCREMENT = 10 を指定することで、シーケンスを任意の番号から開始できます。
  • 🕳️ ギャップが生じる可能性があります。 削除された行やロールバックされたトランザクションは、番号を永続的に消費するため、シーケンスは一意性を保ちますが、連続性は失われます。

MySQL 自動増加

自動インクリメントとは何ですか?

自動インクリメントは、数値データ型を操作する関数です。自動インクリメントとして定義されたフィールドのテーブルにレコードが挿入されるたびに、連続した数値が自動的に生成されます。

この属性は、TINYINTからBIGINTまでのあらゆる整数型に対応しています。また、列にはインデックスが設定されている必要があり、これは主キーとして宣言すると自動的に行われます。

自動インクリメントを使用する場合?

レッスンでは データベース正規化そこで、主キーと外部キーを使って互いに関連付けられた多数の小さなテーブルにデータを格納することで、冗長性を最小限に抑えてデータを保存する方法について検討しました。

MySQL AUTO_INCREMENT と例

主キーはデータベース内の行を一意に識別するため、一意でなければなりません。では、主キーが常に一意であることをどのように保証できるのでしょうか?

考えられる解決策の一つは、主キーを生成する数式を使用し、データを追加する前にテーブル内にキーが存在するかどうかを確認することです。この方法は有効かもしれませんが、複雑で万全ではありません。同時に挿入しようとする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クエリによって生成された最後の自動インクリメント番号が取得されます。結果は以下のとおりです。

MySQL 自動増加

ヒント: LAST_INSERT_ID() は自身の接続にのみ適用されるため、他のユーザーの挿入によって生成された値が誤って返されることはありません。

AUTO_INCREMENTの開始値を設定またはリセットする方法

デフォルトのシーケンスは1から始まりますが、プロジェクトによっては必ずしもそれが適切とは限りません。請求書番号は既存システムから引き継ぐ必要がある場合があり、テストテーブルをリセットする必要が生じることもよくあります。 MySQL カウンターを直接公開することで、どちらの場合も単一の句で処理できます。開始番号を制御するには、以下の手順に従ってください。

  1. 作成時に値を設定します。 CREATE TABLE文にAUTO_INCREMENT句を追加します。そうすると、最初に挿入される行には1の代わりにその番号が割り当てられます。
  2. 既存のテーブルの値を変更します。   他の机 同じ条項で。 MySQL 新しい番号は、現在保存されている最大の識別子よりも大きい場合にのみ受け入れられます。
  3. 空にしたテーブルをリセットします。 TRUNCATE TABLEは、すべての行を削除し、カウンターを1に戻すという一連の操作を1回で実行しますが、DELETE単独ではそれができません。
  4. 変更を確認します。 新しいシーケンスに依存する前に、行を挿入し、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は、複数行挿入のために数値のブロックを予約し、使用しない数値は破棄する場合があります。

これらのギャップを埋めようとするのは間違いです。行番号を振り直すと、それらを指すすべての外部キーが壊れてしまい、値自体にはビジネス上の意味がありません。レポートで連続したリストが必要な場合は、保存されているデータを書き換えるのではなく、クエリで行番号を生成してください。

よくあるご質問

いいえ。 MySQL テーブルごとに 1 つの AUTO_INCREMENT 列のみを許可し、その列にはインデックスを付ける必要があります。 主キー インデックス要件を満たしている。

重複キーエラーが発生し、挿入処理が失敗します。これは、カウンタがデータ型の最大値を超えて進むことができないためです。符号なしTINYINT型は255で停止します。その前に、列のデータ型をBIGINTなどのより広い型に変更してください。

はい、から MySQL バージョン8.0以降では、InnoDBはカウンタをリドゥログに書き込むため、再起動後に復元されます。以前のバージョンではカウンタを再計算し、削除によって解放された数値を再発行する可能性がありました。

部分的に。AIスキーマアシスタントは、次のようなツールに組み込まれています。 MySQL ワークベンチ 記述されたボリュームに十分な幅を持つ符号なし整数を提案してください。推定値は、あなたが提供する成長率の数値に依存するため、それを検証してください。

多くの場合、そうです。AIクエリアシスタントはロールバックされたトランザクションや失敗したトランザクションを指摘します。 INSERT 一般的な原因としては、ステートメントの削除や行の削除などが挙げられます。この説明はあくまで出発点として、サーバーログと照らし合わせて確認してください。