章: 第5章: 設計品質を上げる
テーブル設計で「正規化すべきか、しないべきか」に迷ったことはありませんか?
「とにかく正規化すれば正しい」と思っていると、複雑なJOINが増えてパフォーマンスが劣化したり、集計クエリが毎回重くなったりする問題に直面します。一方で「非正規化でいいや」と安易に判断すると、データの更新異常や整合性の崩壊を招きます。
正規化と非正規化は「保守性」と「性能」のトレードオフです。目的と参照特性を把握したうえで、意図的に使い分けることが設計品質の鍵です。
正規化と非正規化、どう使い分けるか?
基本方針は「まず正規化で設計し、ボトルネックが計測で確認できてから限定的に非正規化する」です。
| 観点 | 正規化 | 非正規化 |
| データの整合性 | 高い(冗長なし) | 低下リスクあり(更新が複数箇所に波及) |
| 書き込み性能 | 高い | 書き込み時に集計値の更新が必要 |
| 読み取り性能 | JOINが増えると低下 | 読み取りが高速になりやすい |
| 向いているケース | マスタ系・更新頻度が高いデータ | 集計・レポート・参照が圧倒的に多いデータ |
| 典型例 | ユーザー情報・注文明細 | 投稿数のカウント・ランキング集計 |
チェックポイント: 非正規化を検討する前に
EXPLAINでボトルネックを特定してください。「なんとなく遅そう」で非正規化すると、保守コストだけが増えて性能は改善されないことがあります。
実際のコードサンプル
-- 例: 集計結果を別テーブルで保持
CREATE TABLE user_stats (
user_id BIGINT UNSIGNED PRIMARY KEY,
post_count INT NOT NULL,
updated_at DATETIME NOT NULL
);
まとめ & 次のステップ
- 設計の出発点は正規化とし、データの冗長をなくす
- 非正規化は「計測でボトルネックが確認できた」後に、限定的な範囲で行う
- 非正規化した箇所は更新タイミングとトリガーを設計に明記しておく
- 集計用の別テーブルを作る場合は、更新漏れを防ぐ仕組み(バッチ・イベント)とセットで考える
- 判断理由をドキュメントに残すと、将来の見直しやレビューで役立つ
次回は パーティションの考え方 を学びます。巨大テーブルの運用負荷を下げるパーティション設計の判断基準を解説します。