列挙型(ENUM) れっきょがた(いーなむ)
ENUM列挙型定数選択肢データベース状態管理
列挙型(ENUM)について教えて
簡単に言うとこんな感じ!
列挙型(ENUM)は「選択肢をあらかじめ決めたラジオボタン」みたいなデータ型だよ!「注文状態」なら「受付中・処理中・発送済・完了」の4択だけOK、それ以外は入力できない!って決められるから、変なデータが入り込む心配がないんだ。
列挙型(ENUM)とは
列挙型(ENUM:Enumeration Type) とは、カラムに入れられる値を「あらかじめ定義した選択肢の中のどれか」に限定するデータ型です。たとえば status カラムを ENUM('pending', 'processing', 'shipped', 'completed') と定義すれば、この4つの値しか格納できなくなります。
「注文ステータス」「性別」「会員ランク」「曜日」など、取りうる値が有限かつ固定的なデータ に使うと非常に相性がよいです。文字列型で保存すると「配送済み」「発送済み」「ship済」など表記ゆれが発生しがちですが、ENUMで定義すれば自動的に統一できます。
ただし、選択肢を後から追加・変更するには ALTER TABLE 文でスキーマを変更する必要があり、稼働中のシステムでは手間とリスクが伴います。選択肢が増えやすい項目には、ENUMの代わりに別テーブル(コードマスタ・参照テーブル)を使う設計が推奨される場合もあります。
各DBMSでのENUMサポート
| DBMS | ENUM対応 | 実装方法 | 注意点 |
|---|---|---|---|
| MySQL | ネイティブ対応 | ENUM('a','b','c') | 内部的には整数インデックスで保存。追加は最後尾なら速い |
| PostgreSQL | カスタム型として対応 | CREATE TYPE mood AS ENUM (...) | 型として定義・再利用できる |
| SQL Server | 非対応 | CHECK 制約で代替 | CHECK (status IN ('a','b','c')) |
| SQLite | 非対応 | CHECK 制約で代替 | 型が緩いため制約で縛る |
| Oracle | 非対応 | CHECK 制約または参照テーブル | 参照テーブル方式が推奨 |
-- MySQLでのENUM定義
CREATE TABLE orders (
id INT PRIMARY KEY,
status ENUM('pending', 'processing', 'shipped', 'completed') NOT NULL DEFAULT 'pending'
);
-- PostgreSQLでの列挙型定義
CREATE TYPE order_status AS ENUM ('pending', 'processing', 'shipped', 'completed');
CREATE TABLE orders (
id SERIAL PRIMARY KEY,
status order_status NOT NULL DEFAULT 'pending'
);
-- 値の追加(PostgreSQL)
ALTER TYPE order_status ADD VALUE 'cancelled';
歴史と背景
- 1970年代 — Pascal言語が列挙型を採用。「
type Season = (Spring, Summer, Autumn, Winter)」のように人間が読める定数の集合として導入 - 1983年 — C言語の
enumが ANSI C で標準化。整数の集合に名前を付ける形で普及 - 1990年代 — Java・C# などのオブジェクト指向言語が列挙型を採用。定数管理の標準手法に
- MySQL 3.23 — RDBMSとしていち早く
ENUM型を実装。文字列の選択肢を整数で内部管理する方式 - PostgreSQL 8.3(2008年) —
CREATE TYPE ... AS ENUMで型として定義できる仕組みを追加。MySQLより柔軟な実装に - 現在 — マイクロサービス・APIファースト設計では「DBのENUMを使わず、アプリ層で列挙値を管理する」設計も増えている
ENUM vs 参照テーブル方式の比較
関連する規格・RFC
| 規格・RFC番号 | 内容 |
|---|---|
| ISO/IEC 9075 (SQL標準) | SQL標準にENUM型の定義は含まれないが、CHECK 制約による同等実装は規定 |