ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
| この記事の要点 |
|
AUTO_INCREMENT の基本
-- 基本定義
CREATE TABLE users (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
created_at DATETIME NOT NULL
);
-- INSERT 時に id 省略 → 自動採番
INSERT INTO users (name, created_at) VALUES ('taro', NOW());
INSERT INTO users (name, created_at) VALUES ('jiro', NOW());
-- id は 1, 2 と振られる
-- 明示的に値を入れることも可能(重複は不可)
INSERT INTO users (id, name, created_at) VALUES (100, 'special', NOW());
-- 次の自動採番は 101 になる
-- 直前に採番された値を取得
SELECT LAST_INSERT_ID();
-- アプリ側からも mysql_insert_id() / PDO::lastInsertId() / PreparedStatement.getGeneratedKeys()
初期値・ステップの変更
-- 開始値を 1000 から
CREATE TABLE orders (
id INT AUTO_INCREMENT PRIMARY KEY,
amount INT
) AUTO_INCREMENT = 1000;
-- 既存テーブルの次採番値を変更
ALTER TABLE orders AUTO_INCREMENT = 5000;
-- → 次の INSERT で id = 5000
-- ステップ(増分)を変更(接続単位)
SET @@auto_increment_increment = 10;
SET @@auto_increment_offset = 1;
-- → 1, 11, 21, 31, ... と採番される
-- マルチマスター構成で重複を避ける用途
ロールバックでも値は消費される
これがよく問題になる挙動です。 AUTO_INCREMENT はトランザクション外で進むため、ロールバックしても番号は戻りません:
-- 現在の次採番値が 10 だと仮定
BEGIN;
INSERT INTO users (name) VALUES ('aaa'); -- id = 10
INSERT INTO users (name) VALUES ('bbb'); -- id = 11
ROLLBACK;
-- 10, 11 は使われずに飛んだ
INSERT INTO users (name) VALUES ('ccc'); -- id = 12(10/11 ではない)
なぜそうなるか: 採番に毎回行ロックを取ると並列性が落ちるので、MySQL は採番処理だけ独立させています。代償として「ロールバックで番号が穴あき」になります。
InnoDB の auto-increment ロックモード
| 値 | 名称 | 挙動 |
|---|---|---|
| 0 | traditional | テーブルレベルのロック。直列化、最も安全だが遅い |
| 1 | consecutive | シンプル INSERT は軽量ミューテックス、バルク INSERT のみテーブルロック。MySQL 8.0 までの既定(5.7) |
| 2 | interleaved | 常に軽量ミューテックス、最速。番号順保証なし。MySQL 8.0 既定 |
-- 現在のモード確認
SHOW VARIABLES LIKE 'innodb_autoinc_lock_mode';
-- 変更(再起動が必要、my.cnf に書く)
-- [mysqld]
-- innodb_autoinc_lock_mode = 2
-- ★ statement-based binlog レプリケーション + mode=2 は組み合わせ不可
-- レプリケーション先で順序がずれる可能性があるため
-- row-based binlog なら mode=2 OK
UNSIGNED と桁あふれ
| 型 | 最大値 (UNSIGNED) | 用途 |
|---|---|---|
TINYINT UNSIGNED | 255 | ステータス系 |
SMALLINT UNSIGNED | 65,535 | マスタコード |
MEDIUMINT UNSIGNED | 16,777,215 | — |
INT UNSIGNED | 4,294,967,295(約 43 億) | ★ 一般的 |
BIGINT UNSIGNED | 18,446,744,073,709,551,615 | 大規模・将来安心 |
21 億で詰まる事故: INT 符号付きの場合 21 億で ERROR 167 (22003): Out of range value。新規テーブルは BIGINT UNSIGNED 推奨(Laravel 8+ のデフォルトもこれ)。
リセット方法
-- テスト環境で番号を 1 に戻したい
TRUNCATE TABLE users;
-- → AUTO_INCREMENT も 1 にリセット
-- DELETE では戻らない
DELETE FROM users;
-- → 次の採番は元のまま
-- 明示的に
ALTER TABLE users AUTO_INCREMENT = 1;
-- ただし既存最大値+1 までしか戻せない
-- 既存 max(id) = 100 のテーブルで AUTO_INCREMENT = 1 にしても、
-- 次採番は 101 になる(重複回避のため)
-- 完全リセットしたい場合
TRUNCATE TABLE users; -- データ全消去 + リセット
DROP TABLE users; CREATE TABLE users ... -- 再作成
PostgreSQL の SERIAL / IDENTITY
-- SERIAL(PostgreSQL 9 以前から使える慣用)
CREATE TABLE users (
id SERIAL PRIMARY KEY, -- 実体は INTEGER + SEQUENCE
name TEXT
);
-- BIGSERIAL なら BIGINT 版
-- IDENTITY(PostgreSQL 10 以降、SQL 標準)
CREATE TABLE users (
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
name TEXT
);
-- BY DEFAULT なら明示値も入れられる
CREATE TABLE users (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
name TEXT
);
-- 次採番値を変更
ALTER SEQUENCE users_id_seq RESTART WITH 1000;
-- IDENTITY の場合
ALTER TABLE users ALTER COLUMN id RESTART WITH 1000;
-- 直近採番値
SELECT lastval();
SELECT currval('users_id_seq');
Oracle の SEQUENCE / IDENTITY
-- 12c 以前: SEQUENCE + トリガ or NEXTVAL
CREATE SEQUENCE seq_users START WITH 1 INCREMENT BY 1;
INSERT INTO users (id, name) VALUES (seq_users.NEXTVAL, 'taro');
-- 12c 以降: IDENTITY 列
CREATE TABLE users (
id NUMBER GENERATED ALWAYS AS IDENTITY,
name VARCHAR2(100)
);
-- SEQUENCE のオプション
CREATE SEQUENCE seq_orders
START WITH 1000
INCREMENT BY 1
NOCACHE -- キャッシュなし(飛びを最小化、性能↓)
NOCYCLE;
SQL Server の IDENTITY
CREATE TABLE users (
id INT IDENTITY(1,1) PRIMARY KEY, -- 初期 1、増分 1
name NVARCHAR(100)
);
-- 直近採番値
SELECT SCOPE_IDENTITY(); -- 現スコープのみ(推奨)
SELECT @@IDENTITY; -- 全スコープ(トリガ起因で別値の罠あり)
-- 明示的に IDENTITY 列に値を入れる
SET IDENTITY_INSERT users ON;
INSERT INTO users (id, name) VALUES (100, 'special');
SET IDENTITY_INSERT users OFF;
-- リセット
DBCC CHECKIDENT ('users', RESEED, 0);
-- → 次採番は 1
ギャップ(番号の飛び)の主な原因
| 原因 | 説明 |
|---|---|
| ROLLBACK | 採番後に取消 → 番号は消費されたまま |
| INSERT ... ON DUPLICATE KEY UPDATE | 重複時も採番カウンタは進む(MySQL 5.7+) |
| INSERT IGNORE | 無視されたレコードでも採番 |
| REPLACE | 削除+挿入なので新採番される |
| サーバー再起動 | MySQL 8.0 まで InnoDB はディスク上の MAX(id) を見て次値決定(5.7 までは再起動でリセット) |
| SEQUENCE のキャッシュ | Oracle のキャッシュ単位で予約 → 未使用分は飛ぶ |
主キーとしての ID か、UUID か
| 項目 | AUTO_INCREMENT | UUID |
|---|---|---|
| サイズ | 4 / 8 byte | 16 byte(VARCHAR(36) なら 36 byte) |
| 連番性 | あり(推測可) | なし |
| 分散採番 | 難しい | 容易 |
| インデックス効率 | 連続 → B-Tree に優しい | ランダム → ページ分割多発 |
| 外部公開 | 推測されると危険 | 安全 |
UUID を使う場合はUUID v7 / ULID(時系列順序を持つ UUID)が B-Tree インデックスに優しくおすすめです。
FAQ
Q: 連番に絶対穴を空けたくない
A: AUTO_INCREMENT では不可能。業務上必要なら採番用テーブルを作って UPDATE seq SET v = v + 1; SELECT v; をトランザクション内で実行(性能と引き換え)。
Q: 既存データを別 DB から移行したい
A: 一旦そのままの id で INSERT → 最後に ALTER TABLE t AUTO_INCREMENT = (MAX(id)+1) で次採番値を調整。
Q: BIGINT UNSIGNED AUTO_INCREMENT の上限到達は現実的か?
A: 約 1844 京。1 秒に 1 億件 INSERT しても 6000 年保ちます。実質無限と考えて OK。
ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
子ページはありません
- テーブル作成
- カラムの定義変更
- カラム名の変更
- カラム追加 / 削除
- インデックスの作成
- インデックスの削除
- AUTO_INCREMENTの仕様について
- AUTO_INCREMENTの追加と確認方法
- 外部キーの追加/削除と制約名の確認方法
人気ページ
- 1 Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法
- 2 tomcat の起動 / 停止ログと catalina.log・catalina.out の違い
- 3 JavaScript で base URL を取得する方法|window.location.origin
- 4 YouTube Data API v3 エラー一覧|403・400・404 の原因と対処
- 5 Laravel エラー一覧|500/Blade/DB 接続/ルーティングの代表エラー
- 6 Spring Frameworkのアノテーション一覧
- 7 3Dグラフィックスとは|モデリング/レンダリング/主要ソフトウェア (Blender / Maya)
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- Spring Bootのテスト入門|@SpringBootTestとJUnitでの単体・結合テスト 2026-08-07 17:15:57
- PHPでのファイルアップロード方法|multipart/form-dataと$_FILES 2026-08-07 17:15:57
- PHP $_SERVERとは|DOCUMENT_ROOT・PHP_SELFなど主な要素 2026-08-07 17:15:57
- Scratchのアカウントの作り方|メールアドレスとユーザー名の登録手順 2026-08-07 17:15:57
- Bluetoothとは|仕組み・BLEとClassicの違い・用途 2026-08-07 17:15:57
- djangoにおけるMVCアプリケーション実装例 2026-08-07 17:15:57
- 【PHPフレームワーク】Laravelの使い方 2026-08-07 17:15:56
- Scratch 作品の公開方法 2026-08-07 17:15:56
- Google OAuth 2.0 認証の実装方法 2026-08-07 17:15:56
- APIキー取得方法 2026-08-07 17:15:56
- データベースとは?RDB / NoSQL / SQL の基礎 2026-08-07 17:15:56
- インストール方法(Windows版) 2026-08-07 17:15:56
- Spring Frameworkの使い方 2026-08-07 17:15:56
- Java とは?言語仕様・JVM・主要フレームワーク一覧 2026-08-07 17:15:56
- インストール(eclipseプラグイン) 2026-08-07 17:15:56
コメントを削除してもよろしいでしょうか?