本記事について
当サイトを閲覧いただきありがとうございます。 本記事はシリーズ『生成AI時代のアーキテクチャ超入門』の「データアーキテクチャ」カテゴリ第3弾として、データモデリングについて解説する記事です。
DBはコードより寿命が長く、数千万行に育ったテーブル構造の変更は数時間のダウンタイムを要します。最初のモデリングが10年後まで効く領域です。本記事では概念/論理/物理の3段階モデリング、正規化と非正規化、主キー設計、インデックス、スキーマ変更戦略、ソフトデリートと履歴管理まで解説し、「AIにも人間にも読めるスキーマ」の作り方を示します。
このカテゴリの他の記事
データモデリングが扱うもの
DBが一度運用されるとテーブル構造の変更は極めて高コストです。数千万行のテーブルにカラムを追加するだけで数時間のダウンタイムを要することもあり、モデリングミスは長期に渡って負債になります。
アプリは書き直せる。データモデルは書き直せないのが現実です。
なぜモデリングが最重要か
① 業務の本質を捉える必要がある
単に「画面に表示するカラム」を並べるのではなく、業務ルールや関係性を構造に落とす必要があります。これを誤ると後のビジネス変更に対応できません。
② 周辺システムに影響が波及する
業務DBは他システム・分析基盤・帳票・BIなど多方向から参照されます。スキーマ変更の影響範囲は想像以上に広く、慎重な設計が必要です。
③ 性能特性が設計で決まる
インデックス・正規化度合い・パーティション戦略など、モデリング段階の決定が将来の性能天井を決めます。後から手を入れると大規模な書き換えが必要です。
モデリングの3段階
データモデリングは3段階で進めるのが定石です。いきなりテーブル定義(物理設計)から入ると業務の本質を掴めず、破綻の元になります。
flowchart LR
BIZ([業務理解])
CON["概念モデル<br/>業務のモノを洗い出す<br/>エンティティ一覧/ER図"]
LOG["論理モデル<br/>属性と関連を定義<br/>正規化"]
PHY["物理モデル<br/>DB製品に合わせた実装<br/>CREATE TABLE/INDEX"]
DB[(本番DB)]
BIZ --> CON --> LOG --> PHY --> DB
BAD[いきなり物理から入る<br/>= 業務の本質を掴めず破綻]
BAD -.->|アンチパターン| PHY
classDef biz fill:#fef3c7,stroke:#d97706;
classDef step fill:#dbeafe,stroke:#2563eb;
classDef db fill:#dcfce7,stroke:#16a34a;
classDef bad fill:#fee2e2,stroke:#dc2626;
class BIZ biz;
class CON,LOG,PHY step;
class DB db;
class BAD bad;
| 段階 | やること | 成果物 |
|---|---|---|
| 概念モデル | 業務で扱う「モノ」を洗い出す | エンティティ一覧・ER図 |
| 論理モデル | 属性と関連を定義・正規化 | 論理ER図・属性定義書 |
| 物理モデル | DB製品に合わせた実装形式 | CREATE TABLE文・インデックス |
大規模なプロジェクトではこの3段階を明確に分けますが、小〜中規模では論理と物理をまとめて進めるのが現実的です。ただし概念モデルだけは必ず先に作るべきです。
正規化とは
正規化は、データの重複を排除し、更新時の矛盾を防ぐための設計原則です。1970年代にE.F. Coddが提唱した理論で、第1正規形〜第5正規形まであります。実務では第3正規形(3NF)までが一般的で、それ以上は理論的・学術的な世界です。
例えば「注文テーブル」に顧客名を書いてしまうと、顧客名の変更時に全ての注文レコードを更新する必要があります。これを「顧客テーブルを別に作って、注文は顧客IDだけ持つ」形に分けるのが正規化です。1箇所の変更で全体が整合する状態を作れます。
| 段階 | 内容 |
|---|---|
| 1NF(第1正規形) | 各セルが1つの値。繰り返し項目を別テーブルに |
| 2NF(第2正規形) | 主キー全体に依存しない列を分離 |
| 3NF(第3正規形) | 主キー以外に依存する列(推移従属)を分離 |
実務では3NFまでやれば十分。4NF・5NFは理論の世界です。
非正規化の考え方
正規化は整合性には優れますが、JOINが増えると性能が落ちるという副作用があります。そこで「意図的に冗長を残す」のが非正規化(デノーマライゼーション)です。分析DBでは非正規化が標準で、業務DBでも読み取り性能が必要な箇所で部分的に適用されます。
| 正規化 | 非正規化 |
|---|---|
| 更新整合性が高い | 更新整合性が落ちる |
| JOINが必要で読み取りが遅い | JOINなしで読み取りが速い |
| OLTP(業務DB)向き | OLAP(分析DB)向き |
| データ重複が少ない | データ重複が多い |
業務DBは3NFで設計 → 必要な箇所だけ非正規化が基本動作で、「最初から非正規化」は危険です。
スター・スキーマ(分析DB向け)
分析DBで最もよく使われるのがスター・スキーマです。中央に「事実(ファクト)」テーブル、周囲に「次元(ディメンション)」テーブルを配置する星型の構造で、集計クエリが高速に回るよう最適化されています。
例えば売上分析なら:
- ファクトテーブル:売上明細(日時・商品ID・顧客ID・金額)
- ディメンションテーブル:商品・顧客・日付・店舗
この形にすると「地域別・月別・商品カテゴリ別の売上」のような多軸集計が極めて高速になります。BigQuery・Snowflake・Tableau など分析基盤はほぼ全てこの形を前提にしています。
業務DBは3NF、分析DBはスター・スキーマ。用途で形を変えます。
主キーの設計
主キーは各レコードを一意に特定するIDで、選び方が後の設計に大きく影響します。実務では自動採番のサロゲートキー(連番・UUID)が主流で、業務的な値(メールアドレス・電話番号等)を主キーにするのは避けるのが鉄則です。
業務値を主キーにすると、その値が変わったときに全ての外部参照を更新する必要があり、改姓・メール変更といった現実の業務変化に耐えられません。
| 主キー種別 | 特徴 | 向くケース |
|---|---|---|
| 連番(BIGINT) | 小さくて速い・順序あり | 業務系DB・内部利用のみ |
| UUID v4 | 分散生成可・順序なし | 分散システム・外部公開 |
| UUID v7 | 時刻順序あり・分散生成可 | 2024年以降の新規DB |
| 業務値 | 意味が読み取れる | 原則使わない |
現代はUUID v7(2024年RFC化)が時刻順とランダム性を両立する最適解として評価されています。
新規DBの主キーはUUID v7またはBIGINT。v4はインデックス性能劣化を招きます。
インデックス設計
インデックスは検索を高速化する補助データ構造で、正しく張ると数百倍速くなる一方、張りすぎると更新が遅くなり、DBを肥大化させます。「WHEREとJOINに使うカラムには張る、それ以外は張らない」が基本方針です。
複合インデックスは順序が重要で、左から前方一致でしか効きません。(a, b, c) のインデックスは WHERE a=?・WHERE a=? AND b=?・WHERE a=? AND b=? AND c=? には効きますが、WHERE b=? だけには効きません。
| インデックス種別 | 用途 |
|---|---|
| B-Tree | 標準・等値検索・範囲検索 |
| Hash | 等値検索のみ(使い所は狭い) |
| GIN / GiST | 全文検索・JSON・地理情報 |
| 部分インデックス | 条件付き(削除済み除外など) |
初期は必要最小限で張り、実クエリで遅いものにだけ後から追加するのが鉄則です。
スキーマ変更戦略(マイグレーション)
運用中のDBのスキーマ変更は最も事故りやすい領域です。カラム追加・削除・型変更・制約変更のそれぞれで危険度が違い、「後方互換を保ちながら段階的に変更する」のが定石です。
| 変更 | 危険度 | 戦略 |
|---|---|---|
| カラム追加(NULL許可) | 低 | 直接追加してOK |
| カラム追加(NOT NULL) | 中 | 一旦NULL許可→バックフィル→NOT NULL |
| カラム削除 | 中 | 先にコード側で使用停止→後日削除 |
| 型変更 | 高 | 新カラム追加→データ移行→切替 |
| リネーム | 高 | 両方存在させる→段階切替 |
マイグレーションツール(Flyway・Liquibase・Prisma Migrate・dbt 等)でGitで履歴管理するのが必須です。手動でDBを直接変更するのは事故の元です。
ソフトデリートと履歴管理
削除されたレコードをどう扱うかは、設計で必ず決めておくべき項目です。選択肢は大きく3つで、業務要件と法的要求によって決まります。
| 方式 | 内容 | 向くケース |
|---|---|---|
| 物理削除 | レコードをDBから消す | キャッシュ・ログ・監査不要データ |
| ソフトデリート | deleted_at カラムで論理削除 | 業務データ全般 |
| 履歴テーブル | 変更を別テーブルに蓄積 | 金融・監査対象・法的要件あり |
GDPR等の個人情報削除要求があると物理削除が必須になる場面もあります。ソフトデリートと法令の両立は事前に要件を詰めておく必要があります。
金融・医療・公共は履歴テーブルが法的必須のケースが多いため、業務要件を確認します。
判断基準
① 業務の複雑度
業務の複雑度によって必要なモデリング深度が変わります。単純なCRUDアプリなら3NFだけで十分ですが、業務ルールが複雑になるほどDDD(ドメイン駆動設計)の集約境界を意識したモデリングが必要になります。
| 複雑度 | 推奨アプローチ |
|---|---|
| 単純CRUD(社内ツール・管理画面) | 3NFで素直に作る |
| 中規模業務(EC・SaaS) | 3NF + 集約境界を意識 |
| 高度な業務(金融・保険・医療) | DDD + イベント・履歴保持 |
② スケール想定
想定する規模がモデリングに影響します。将来大量データを扱う予定なら、パーティション戦略(1つのテーブルを内部的に時期・顧客IDで複数領域に分割)やシャーディング(水平分散、複数DBに分散配置)を初期設計で考慮します。
- 100万レコード未満:何も考えなくてOK
- 1000万〜:主要テーブルのパーティション検討
- 1億〜:パーティション・シャーディング必須・非正規化も検討
③ チームの力量
モデリングはチーム全体のSQL・DB理解度に依存します。高度なモデル(EAV(Entity-Attribute-Value)・Polymorphic・イベントソーシング等)はチームが扱いきれないと地獄になります。
| チームの力量 | 推奨レベル |
|---|---|
| SQL初級・DB設計初めて | 素直な3NF・余計な工夫なし |
| 中級・DB設計経験あり | 3NF + ソフトデリート + 履歴 |
| 上級・DDD経験あり | DDD集約・イベントソーシング |
ケース別の選び方
社内管理画面・シンプルなCRUD
3NFで素直に設計。UUID v7 + ソフトデリート + 監査カラム(created_at・updated_at)程度でOKです。
EC・SaaSの業務DB
3NF + 履歴保持。注文履歴・価格変更履歴は別テーブルで保持します。分析DBは別途用意し、ETL/ELTで同期します。
金融・医療・公共
履歴テーブル必須・物理削除禁止。全変更を別テーブルに蓄積し、監査対応できるようにします。
分析基盤(DWH)
スター・スキーマ。業務DBのデータをETLで非正規化して投入します。BigQuery・Snowflakeのベストプラクティスに従います。
テーブル数値Gate・インデックス設計の閾値
※ 2026年4月時点の業界相場値です。テクノロジー・人材市場の変化で陳腐化するため、定期的にアップデートが必要です。
モデリング品質を数値で追うのが現代の標準です。以下が業界定番の目安です。
| 指標 | 閾値 | 超えたらどうするか |
|---|---|---|
| 1テーブルのカラム数 | 20個以下 | 責務が混在。分割を検討 |
| 1テーブルの行数(通常) | 〜1億行 | それ以上はパーティション検討 |
| 1テーブルのインデックス数 | 5個以下 | 更新性能劣化。見直し |
| JOINの深さ | 3〜4段まで | それ以上は非正規化 or ビューで整理 |
| スキーマ変更(大テーブル) | 1時間以内でdownなし | online DDL / pg_repack 等を使う |
| 複合インデックスの列数 | 3列以下 | それ以上は使い道が限定的 |
| NULL許容列の割合 | できるだけNOT NULL | 制約を効かせる |
| 主キー型 | UUID v7 または BIGINT | v4はインデックス性能劣化 |
「1000万行超のテーブル」は ALTER TABLE で数分〜数時間の lock が発生するため、PostgreSQL なら pg_repack / MySQL なら gh-ost / pt-online-schema-change を使った無停止変更が必須。expand/contractパターン(列追加→両方書き→切替→旧列削除の4段階)で運用するのが鉄板です。
数値GateはESLint / SonarQubeのDB版。機械的にチェック可能です。
筆者メモ — 「metadata JSONB」が生んだフルスキャン地獄
ある業務アプリでは、ユーザープロフィールの全属性が metadata という1つの JSONB(JSON Binary、高速インデックス検索可能なJSON保存型)カラムに詰め込まれていた、という話がしばしば語られます。「将来の拡張に備えて柔軟に」が動機だったものの、「会社名にXを含むユーザー」を絞り込むだけで毎回フルスキャンが走る状態になり、データ量が増えるにつれて管理画面が開かなくなったと言います。
筆者も類似の現場を見たことがあり、数十万件のユーザーを検索するUIが3秒以上かかるようになって初めて問題が発覚した、という展開をよく覚えています。GINインデックスで応急処置しても通常カラムよりはるかに遅く、結局主要属性を通常カラムに分離する大改修で半年を費やした、というオチまでがセットで語られる事例です。
似た話で、主キーに UUID v4 を採用したところ、レコードが増えるにつれて「インデックスの物理配置が分散して」書き込みが重くなり、数千万件規模で性能劣化が顕著になった事例もあります。2024年以降はUUID v7(時刻順序あり)が標準化され、この問題は設計段階で回避できるようになりました。「柔軟に」と「雑に」は紙一重、というのが両事例に共通する教訓です。
JSONはスキーマが揺れる一部領域だけに限定。検索対象は通常カラムに切り出します。
データモデリングの鬼門・禁じ手
モデリングで事故る典型を整理します。スキーマはDBの骨格なので、後から直すのが最も高コストな領域です。
| 禁じ手 | なぜダメか |
|---|---|
| 物理削除で履歴を残さない業務 | 監査対応・法的要件で即詰む。金融・医療・税務は履歴テーブル必須 |
| 全列をNULL許容で作る | 制約が効かず、データ品質が漸減。必須項目はNOT NULL |
| JSONBに検索対象を詰め込む | GINインデックスでも通常カラムより遅い。主要属性は通常カラム |
| UUID v4 を主キーに大量挿入 | インデックス局所性が悪化。UUID v7(時刻順)かBIGINT |
| メールアドレス・電話番号を主キーに | 改姓・メール変更で全外部キー更新の大工事 |
tmp_ / bak_ / old_ テーブルを本番に残す | 数年後に「消していいか」分からない負債 |
| 外部キー制約を性能のために全部外す | 整合性破壊・孤立データ蓄積。上級者以外は付ける |
| マイグレーションをGUI手作業 | 履歴・再現・ロールバック不可。Flyway / Prisma Migrate / Liquibase で Git 管理 |
命名を日本語ローマ字(chushin_jusho) | AIも人も読めない。英語snake_caseが標準 |
| インデックスを予防的に全列に張る | 更新ごとに全インデックス更新で書き込み遅延。クエリ実測で張る |
| スキーマ変更を本番営業時間に実施 | lockで本番停止。メンテ時間 or online DDL |
2024年のUUID v7 RFC化(RFC 9562)は、UUID v4のランダム性とタイムスタンプを両立させる新版で、新規プロジェクトではv7が鉄板です。UUID v4を採用したレガシーシステムのインデックス性能劣化は、2020年代に頻繁に報告された問題です。
外部キー制約は整合性を担保する最後の砦。性能を理由に切るのは典型的な悪手です。
AI時代の視点
AI駆動開発(バイブコーディング)とAI活用が前提になると、データモデリングはAIが読んで理解できる構造であることが重要になります。スキーマが明示され、テーブル名・カラム名が自然言語として意味を持つDBは、AIがSQLを正確に生成できます。逆に略語・意味不明な命名・JSON乱用のDBはAIの生成精度を下げます。
| AI時代に有利 | AI時代に不利 |
|---|---|
| 3NFで構造が明確・命名が明快 | JSON乱用・スキーマレス |
| 英語の自然な命名(users・orders) | 略語・日本語ローマ字命名 |
| 外部キー制約が明示されている | 制約なしで関連が推測必要 |
| コメントで業務的意味を記述 | コメントなしの裸テーブル |
AIエージェントがText-to-SQLでDBを操作する時代、「スキーマそのものが文書」になる必要があります。命名とコメントの質がAI生成精度に直結します。
AIに優しいスキーマは、長期保守の観点では人間にも優しい方向に重なります。明示的な3NF・英語の自然な命名が最強です。
よくある勘違い
- とりあえずJSONカラムで柔軟にしておけば安心 → JSON乱用はスキーマレスの罠。検索・インデックスの効きが悪く、規模が増えると破綻します。JSONは「スキーマが揺れる一部領域」に限定します
- IDはUUID v4一択 → v4はランダムすぎてインデックス効率が落ちます。UUID v7が時刻順序とランダム性を両立する現代の最適解です
- 外部キー制約は面倒だから切る → 外部キー制約は整合性を担保する最後の砦。性能のために切るのは上級者の判断で、初期は必ず付けます
- 正規化すればするほど良い → 4NF以降は学術世界です。3NFで止めて「JOIN性能を確保」するのが実務の正解です
決めるべきこと — あなたのプロジェクトでの答えは?
以下の項目について、あなたのプロジェクトの答えを1〜2文で言語化してみてください。曖昧なまま着手すると、必ず後から「なぜそう決めたんだっけ」が問われます。
- 正規化レベル(3NFが基本)
- 主キー戦略(UUID v7を推奨)
- ソフトデリート方針(deleted_atカラム / 履歴テーブル)
- 監査カラム(created_at・updated_at・created_by)
- 命名規則(英語snake_caseが標準)
- マイグレーションツール(Flyway・Prisma Migrate等)
- インデックスの初期セット
最終的な判断の仕方
データモデリングの核心は業務の本質を構造に落とすことであり、画面に表示するカラムを並べる作業ではありません。DBが運用されるとスキーマ変更は極めて高コストになり、数千万行のテーブルはカラム追加だけで数時間のダウンタイムを要します。だからこそ概念モデルから論理→物理の順に業務の骨格を先に固め、「業務DBは3NF・分析DBはスター・スキーマ」という用途別の基本形を守るのが合理的です。過度な正規化(4NF以降)も、最初から非正規化も、どちらも実務では不要な寄り道になります。
決定的な軸はAIが読めるスキーマかという問いです。Text-to-SQLでAIがDBを操作する時代、スキーマそのものが仕様書として機能します。英語の自然な命名・明示的な外部キー制約・業務的意味を記したコメントが揃ったDBはAIの生成精度を大幅に上げます。逆に略語・日本語ローマ字・JSON乱用のDBは、AIの生成精度を落としてしまいます。
選定の優先順位
- 業務DBは3NF — 4NF以降は学術の世界、3NFで止めてJOIN性能を確保する
- UUID v7 + ソフトデリート + 監査カラム — 2024年以降の新規DBの標準セット
- 英語の自然な命名 + コメント — AI生成精度を上げ、将来のText-to-SQLに備える
- マイグレーションをGit管理 — Flyway / Prisma Migrateで履歴を追える状態にする
「AIにも人間にも読めるスキーマ」3NFで明示的に、命名で意図を伝えます。
まとめ
本記事はデータモデリングについて、概念・論理・物理の3段階・3NFと非正規化・主キー設計・インデックス・スキーマ変更戦略・ソフトデリートと履歴管理まで含めて解説しました。如何だったでしょうか。
業務DBは3NF、UUID v7+ソフトデリート+監査カラムを標準セットに、英語の自然な命名でAI生成精度を上げる。これが2026年のデータモデリングの現実解です。
次回はデータ基盤(DWH・データレイク・BI連携)について解説します。
シリーズ目次に戻る → 『生成AI時代のアーキテクチャ超入門』の歩き方
それでは次の記事も閲覧いただけると幸いです。
📚 シリーズ:生成AI時代のアーキテクチャ超入門(41/89)