変更要約: 初版
2.5論理設計から物理設計へ
正規化された論理設計を実際の格納方式に落とし込む物理設計、性能目的で意図的に冗長性を持たせる非正規化、そして正規化と非正規化のトレードオフ、結合コストと冗長のバランスをどう取るかという設計判断を学びます。
これまでの節で学んだ正規化は「論理設計」の話であり、更新時異常の排除という正しさを追求する作業でした。しかし実際にシステムを運用すると、正規化しすぎたスキーマはJOINの多発による参照性能の低下という現実の壁にぶつかります。DB設計者は最終段階で、論理設計をそのまま物理的な格納方式に落とし込むのか、それとも一部を意図的に非正規化して性能を優先するのかを判断しなければなりません。この節では、論理設計と物理設計の違いと、非正規化という最後の設計判断を学びます。
2.5.1論理設計と物理設計の違い
- 論理設計=業務要件をE-R図・正規化された関係スキーマとして表現する工程。DBMSの製品や具体的な格納方式に依存しない、What(何を管理するか)を定める段階。
- 物理設計=論理設計を実際のテーブル・インデックス・パーティション・格納領域(テーブルスペース等)へ落とし込む工程。How(どう格納し、どう高速にアクセスするか)を定める段階で、性能要件・データ量の見積り・アクセスパターンの分析が入力になる。
2.5.2非正規化のトレードオフ
- 非正規化=正規化によって分離した情報を、性能目的で意図的に一部の表へ再び重複格納すること(例:注文明細表に、本来は商品表から都度JOINして得るべき商品名を冗長にコピーしておく)。JOIN回数を減らし参照性能を上げる代わりに、更新時異常のリスクを意図的に許容するトレードオフである。
- 非正規化は「正規化を知らずに崩す」のではなく、まず正規化された論理設計を確立した上で、性能要件(参照頻度・データ量・許容レイテンシ)を踏まえてどこを意図的に崩すかを選ぶ、後工程の最適化判断として行うのが正しい手順。冗長化した列は、更新時に元データとの同期を保つ運用(トリガ等)とセットで設計する。
「論理設計=Whatを定める(正規化されたE-R図・関係スキーマ)」「物理設計=Howを定める(テーブル・インデックス・パーティション)」「非正規化=性能目的の意図的な冗長化」が最頻出です。「非正規化は正規化の失敗である」という誤解に注意——非正規化は正規化を理解した上での意図的なトレードオフの選択であり、順序としては必ず正規化の後に検討するものです。
あるECサイトのデータベース設計者が、正規化された「注文明細」表(注文明細ID, 注文ID, 商品ID, 数量)と「商品」表(商品ID, 商品名, 単価)を運用しています。トップページの「注文履歴一覧」画面は1日数万回アクセスされる高頻度の参照処理で、毎回「注文明細」表と「商品」表をJOINして商品名を取得しているため、アクセス集中時にレスポンスが数秒遅延するという性能問題が発生しました。設計者はまず、この画面のためだけにJOINを避ける非正規化を検討します——「注文明細」表に商品名の列を冗長に追加し、注文確定時点の商品名をコピーして持たせる設計です。ここで重要な判断があります。商品名は将来的に変更されることがありますが、「注文履歴には注文当時の商品名を表示すべき」という業務要件がある場合、この非正規化はむしろ正しい設計です(コピーされた商品名は「その時点のスナップショット」という別の意味を持つため、後から商品名が変わっても更新する必要がない)。一方、もし「常に最新の商品名を表示すべき」という要件であれば、非正規化した列を商品名変更時に同期するトリガや更新処理を追加で設計する必要があり、その同期処理の複雑さとバグ混入リスクを天秤にかけなければなりません。この設計者は、注文履歴は法的にも「注文当時の記録」を残す性質のものであるため、同期不要なスナップショットとして非正規化するのが最も理にかなっていると判断し、さらに参照頻度の高い注文ID列には物理設計としてインデックスを追加することで、正規化のトレードオフと物理設計の両輪で性能問題を解消しました。
| 設計段階 | 定める内容 | 主な成果物 |
|---|---|---|
| 論理設計 | 業務要件をWhat(何を管理するか)として表現 | E-R図・正規化された関係スキーマ |
| 物理設計 | How(どう格納し高速アクセスするか)を決定 | テーブル定義・インデックス・パーティション |
| 非正規化 | 性能目的で意図的に冗長性を許容 | 冗長列+同期の運用設計(要否は業務要件次第) |
ひっかけ: 「非正規化は正規化の理解不足による設計ミスである」は誤りです——非正規化は正規化された論理設計を確立した上で、性能要件を踏まえて意図的に選ぶ後工程の最適化判断です。また「非正規化した冗長列は常に元データと同期させなければならない」も誤りで、「注文当時の商品名」のように、その冗長データが独自の意味(スナップショット)を持つ場合は、意図的に同期しない設計の方が正しいことがあります。
2.5.3この節のまとめ
- 論理設計=Whatを定める(正規化されたE-R図・関係スキーマ)、物理設計=Howを定める(テーブル・インデックス・パーティション)
- 非正規化は正規化を理解した上での意図的な冗長化。正規化の後工程として、性能要件に基づき選択的に行う
- 冗長データが「スナップショット」等の独自の意味を持つ場合、同期不要な非正規化の方が正しい設計になることがある
進捗の記録にはログインが必要です。
理解度チェック
(軽い確認用)Q1. 「注文明細」表と「商品」表をJOINして商品名を取得している「注文履歴一覧」画面が、高頻度アクセスによりレスポンス遅延を起こしている。業務要件として「注文履歴には注文当時の商品名を表示すべき」とされている場合、最も妥当な対応はどれか。
Q2. 前問の状況で、もし業務要件が「常に最新の商品名を表示すべき」に変わった場合、非正規化した商品名列を運用する上で追加で必要になる設計対応として最も適切なものはどれか。
Q3. あるDB設計者が「正規化は面倒なので、最初から性能を優先してすべての表に冗長列を持たせた物理設計だけを行う」という方針を採ろうとしている。この方針の妥当性として最も適切な評価はどれか。

