🎓 レベル:標準 | 重要度:A(必須)
📎 前提:リレーショナルモデルと正規化・ER図とスキーマ設計 | 関連:正規化と非正規化のトレードオフ・データウェアハウス
要点(BLUF)
- 次元モデリングは、分析のために**ファクト(測りたい数値の事実:売上・数量)とディメンション(切り口:商品・日付・店舗)**を分けて持つ設計。
- 中心のファクトテーブルを、複数のディメンションテーブルが星型に囲むのがスタースキーマ。「カテゴリ別・月別の売上」のような集計が、素直なJOIN+GROUP BYで書ける。
- 設計の核は粒度(grain)=ファクト1行が表す事実の細かさを最初に決めること。粒度がぶれると集計が二重計上で壊れる。
概念 ── 「事実」と「切り口」を分ける
分析の問いはたいてい「何を(指標)/どの切り口で見たいか」の形です。「売上(指標)を、商品カテゴリ別・月別(切り口)で」。この“指標”がファクト、“切り口”がディメンションです。
flowchart TB
DP["dim_product(商品)"] --> F["fact_sales(売上ファクト)"]
DD["dim_date(日付)"] --> F
DS["dim_store(店舗)"] --> F
DC["dim_customer(顧客)"] --> F
ファクトは数値と外部キーだけを細く長く持ち、ディメンションはテキストの属性を持って横に広い。この形が、分析クエリと相性抜群です。
仕組み ── スタースキーマでの集計
erDiagram
DIM_PRODUCT ||--o{ FACT_SALES : "product_key"
DIM_DATE ||--o{ FACT_SALES : "date_key"
FACT_SALES {
int sales_id PK
int product_key FK
int date_key FK
int quantity
int amount
}
DIM_PRODUCT {
int product_key PK
text name
text category
}
DIM_DATE {
int date_key PK
text ymd
text month
}
SELECT p.category, d.month,
SUM(f.quantity) AS qty, SUM(f.amount) AS sales
FROM fact_sales f
JOIN dim_product p ON f.product_key = p.product_key
JOIN dim_date d ON f.date_key = d.date_key
GROUP BY p.category, d.month
ORDER BY sales DESC;
実行結果(実機・SQLite):
category | month | qty | sales
Drink | 2026-06 | 9 | 2650
Food | 2026-06 | 6 | 2400
ファクトを中心に、欲しい切り口のディメンションをJOINしてGROUP BYするだけ。切り口を足したいなら別のdimをJOINするだけで拡張できます。これがスタースキーマの“読みやすさ”です。
設計の勘所 ── 粒度・SCD・スノーフレーク
- 粒度(grain):ファクト1行=「1回の販売明細」なのか「1日の店舗合計」なのか。最初に1文で宣言する。粒度を混在させると二重計上で集計が壊れる。
- SCD(緩やかに変化する次元):商品カテゴリが時間で変わるとき、履歴を残すか上書きするか。残すなら有効期間の列を足す(SCD Type 2)。
- スノーフレーク:ディメンションをさらに正規化して分割した形。JOINが増え可読性が落ちるため、分析用途では**スター(非正規化したdim)**が基本。
なぜそうするか ── 分析に最適化した非正規化
なぜ リレーショナルモデルと正規化 で学んだ正規化に逆らい、ディメンションをあえて非正規化(カテゴリ名を商品dimに直書き)するのか。分析は読み取りが主で更新が少ないからです。更新時異常のリスクが小さい一方、JOINを減らせばクエリが速く・SQLが単純になる。OLTP(更新系)と違い、OLAP(分析系)では読みやすさ・速さ>更新の厳密さ。この判断軸の全体像が 正規化と非正規化のトレードオフ です。
⚠️ よくある落とし穴
- 粒度を宣言せずに作る → 明細行と日次集計行が混ざり、SUMが二重になる。1行が表す事実を最初に文章で固定。
- ファクトにテキスト属性を詰め込む → ファクトが太り遅くなる。テキストはディメンションへ、ファクトは数値とキーだけ。
- 次元の変化(改名・統廃合)を上書きで握りつぶす → 過去の集計が再現できなくなる。履歴が要るならSCD Type 2。
対応ラボ
data-engineering-study/labs/02_data_modeling.py(PYTHONIOENCODING=utf-8 で実行・上記の集計を確認済み)。
- 確認できること:ファクト×ディメンションのJOIN集計、カテゴリ×月の売上
関連
- 土台の正規化は リレーショナルモデルと正規化、関係設計は ER図とスキーマ設計
- 使い分けの判断は 正規化と非正規化のトレードオフ
- この設計を載せる分析基盤は データウェアハウス、層構造での整え方は メダリオンアーキテクチャ