はじめに
アプリケーション開発では、区分値やステータスなどのマスタデータをどう管理するかは、悩みどころである気がします。
設計として、選択肢は下記の2つ。
- enumでコードとして管理
- DBのマスターテーブルで管理
どちらも正解になりうる反面、誤った判断をすると将来的に変更コストが増えたり、運用が破綻したりします。
本記事では、開発現場でよく議論されるポイントを整理し、どう判断すべきかを基準化します。
enumとマスターテーブルのざっくり比較
| 観点 | enum | マスターテーブル |
|---|---|---|
| 変更頻度 | ほぼ変わらない場合向き | 変更・追加の可能性がある場合 |
| 変更者 | エンジニア | 非エンジニア/業務ユーザーも含む |
| 多言語・並び順・付随情報 | 管理しづらい | 柔軟に対応可能 |
| リリースの必要性 | 必須 | 不要(INSERT/UPDATEでOK) |
| 集計/分析用途 | 弱い | SQL・BIで活用可能 |
| コード依存度 | 高い(アプリと強く紐付く) | 低い(データ駆動) |
| 他システム連携 | 不向き | 向いている |
enumを使うべきケース
ざっくり例
「もう変わらない」「アプリロジックが依存している」もの。
| 値 | 判定理由 |
|---|---|
| 性別(Male / Female / Other) | ほぼ変わらない、仕様固定 |
| ロール種別(ADMIN / SYSTEM / USER) | 挙動が分岐する、ロジック依存が強い |
| HTTPステータス種別 | 定義済み規格、外部依存がない |
enumが向いている理由
enumを使うメリットとして大きいのは、まず、コンパイル時に値がチェックされること。
存在しないコードやタイプミスがある場合は実行前にエラーとして検知できるため、バグが潜り込みにくい。
また、IDEの補完が効くため、文字列を手入力する必要がなく、開発時の入力ミスや表記ゆれを防げる。
さらにenumは多くの場合、ソースコード側の制御構造(switchやif条件分岐)と密接に結びついている。
処理ロジックとデータが同じ場所で完結するため、読みやすく整理されたコードになり、後から仕様を追う際にも理解しやすい。
マスターテーブルを使うべきケース
ざっくり例
| 値 | 理由 |
|---|---|
| 都道府県・市区町村 | データ量が多い、増減あり |
| 顧客区分、商品種別、料金体系 | 業務ルール変更がありうる |
| ステータス + 表示順 + 表示名(多言語) | 属性が増えるほどコード管理は破綻 |
マスターテーブルが向いている理由
マスターテーブルで管理する場合の利点は、DBを参照・更新するだけで変更が反映されるため、リリースが不要になること。
運用中に値が追加・修正される可能性があるケースでは、この柔軟性が大きなメリットとなる。
さらに、コードやラベルがデータとして存在するため、他システムとの ID・コードマッピングがしやすく、外部連携にも向いている。
マスターテーブルはSQLで、直接参照できるため、集計や分析用途でも強く、データ活用の幅が広いという特徴がある。
どっちにすべき?判断フロー
以下に当てはまるほどマスターテーブル推奨。
❓ その値はユーザーが管理・追加する可能性がある?
├─ Yes → マスターテーブル(管理画面つくる)
└─ No
❓ 多言語・並び順・付加情報が必要?
├─ Yes → マスターテーブル
└─ No
❓ 将来的に増えるか・変わる可能性がある?
├─ Yes → マスターテーブル
└─ No → enum
状況QA
Q. データは少ないが変わる可能性がある場合は?
A. テーブルが無難。変更頻度は未来には読めない。
Q. enumだけど表示名だけ変えたい場合は?
A. enum + ラベルだけDBというハイブリッド構成も検討する。
少し詳しく
【ユーザーに表示する文言だけ変えたいイメージ】
| enum | UI表記(最初) | UI表記(後から変えたい) |
|---|---|---|
| Pending | 承認待ち | 保留 |
| Shipped | 発送済み | 配送完了 |
| Cancelled | キャンセル | 中止 |
【enumイメージ】
enum OrderStatus {
Pending = 'PENDING', // 支払い前処理
Shipped = 'SHIPPED', // 請求処理実行
Cancelled = 'CANCELLED', // 停止
}
【テーブルイメージ】
label_jaを変えるだけで良い!
| status_code | label_ja | label_en |
|---|---|---|
| PENDING | 保留 | Pending |
| SHIPPED | 配送完了 | Shipped |
| CANCELLED | 中止 | Cancelled |
上記のように定義することで、下記の使い分けができる!
ロジック → enumを使う
画面表示 → DBのラベルを見る
Q. テナントごとに値を変えたい場合は?
A. テーブル管理。enumでは対応不可。
まとめ
ロジックに深く関わり、システムの挙動そのものを左右する値は、原則としてenumで管理するのが適している。
enumで管理する値は仕様上の意味を持ち、変更によって処理フローや外部連携に影響が出るため、むやみに変えるべきではない。
一方で、画面表示やユーザー操作、運用ルールと結びつくようなデータは、マスターテーブルとして管理する方が柔軟で運用しやすい。
特に表示名の変更や追加が発生し得る場合、DBで管理することでリリースや開発作業を介さずに変更が可能となり、業務側だけで完結できる。
enum = システムのための値
マスターテーブル = ユーザーと業務のための値