🏗️ STEP 32: データモデリングの基礎
データの設計図を理解しよう!効率的なモデルの作り方
📋 このステップで学ぶこと
- データモデルとは何か(役割と必要性)
- ファクトテーブルとディメンションテーブルの違い
- リレーションシップの概念と設定方法
- カーディナリティ(1対多、多対多)の理解
- 正規化と非正規化の考え方
- 良いデータモデルの設計原則
ゴール:効率的で分析しやすいデータモデルを設計できるようになる
🎯 1. データモデルとは
データモデルの役割を理解しよう
データモデルとは、複数のテーブルがどのように関連しているかを定義した設計図です。家を建てるときに設計図が必要なように、データ分析でもこの「設計図」が重要な役割を果たします。
| 要素 | 説明 | 例え |
|---|---|---|
| テーブル | データを格納する表 | 家の「部屋」のようなもの |
| リレーションシップ | テーブル同士のつながり | 部屋を結ぶ「廊下」のようなもの |
| キー | テーブルを識別する列 | 部屋の「番号」のようなもの |
| データ型 | データの種類(数値、文字など) | 部屋の「用途」のようなもの |
なぜデータモデルが重要なのか
Power BIでレポートを作成する際、データモデルの良し悪しが分析の成功を左右します。適切なデータモデルがないと、様々な問題が発生します。
| 項目 | 良いデータモデル | 悪いデータモデル |
|---|---|---|
| 処理速度 | クエリが高速で実行される | クエリが遅く、待ち時間が長い |
| メモリ使用 | 効率的でメモリを節約 | 大量のメモリを消費 |
| 計算の作成 | DAX式がシンプルに書ける | 複雑な計算式が必要 |
| メンテナンス | 変更が1箇所で済む | 複数箇所の修正が必要 |
| 拡張性 | データ増加に対応可能 | データ増加で破綻する |
| エラー発生 | エラーが起きにくい | 頻繁にエラーが発生 |
モデルビューでデータモデルを確認する
Power BIでは「モデルビュー」という画面でデータモデルを視覚的に確認・編集できます。テーブル間の関係が線で表示され、全体像を把握できます。
| 手順 | 操作 | 補足 |
|---|---|---|
| 1 | Power BI Desktopを開く | データが読み込まれている状態 |
| 2 | 左サイドバーの3番目のアイコン(🔗)をクリック | レポートビュー、データビューの下にある |
| 3 | テーブルがボックスで表示される | ドラッグで位置を変更可能 |
| 4 | テーブル間の線を確認 | 線がリレーションシップを表す |
| 表示要素 | 意味 | 確認ポイント |
|---|---|---|
| テーブルボックス | 各テーブルを表す四角形 | テーブル名とフィールド一覧が表示 |
| 実線 | アクティブなリレーションシップ | 通常使用される関係 |
| 点線 | 非アクティブなリレーションシップ | 特別な場合のみ使用 |
| 1 と * の記号 | カーディナリティ(関係の多重度) | 1=1件、*=複数件 |
| 矢印 | フィルターの伝播方向 | どちらからフィルターが効くか |
| 鍵アイコン | 主キー(一意の識別子) | 重複がない列に表示 |
📊 2. ファクトテーブルとディメンションテーブル
2種類のテーブルを理解しよう
データモデルでは、テーブルは大きく2種類に分類されます。この分類を理解することが、良いデータモデル設計の第一歩です。
| 特徴 | 説明 |
|---|---|
| 役割 | ビジネスの「事実」「出来事」を記録するテーブル |
| データの内容 | 数値データ(売上金額、販売数量、コストなど)が中心 |
| 行数 | 多い(数万〜数百万行、時には数億行) |
| 変更頻度 | 高い(日々の取引で新しいデータが追加される) |
| キーの種類 | 外部キーを持つ(他のテーブルを参照する) |
| 具体例 | 売上データ、注文履歴、取引記録、アクセスログ |
覚え方:「何が」「いつ」「いくつ」「いくら」という事実を記録するテーブル
| 特徴 | 説明 |
|---|---|
| 役割 | ファクトを「説明」「分類」するためのテーブル |
| データの内容 | テキストデータ(商品名、顧客名、地域名など)が中心 |
| 行数 | 少ない(数十〜数千行程度) |
| 変更頻度 | 低い(マスタデータなので頻繁には変わらない) |
| キーの種類 | 主キーを持つ(一意の識別子) |
| 具体例 | 商品マスタ、顧客マスタ、店舗マスタ、日付マスタ |
覚え方:「誰が」「どの商品を」「どの店で」という属性情報を格納するテーブル
具体例:ECサイトのデータモデル
オンラインショップを例に、ファクトテーブルとディメンションテーブルがどのように構成されるか見てみましょう。
| 売上ID | 日付ID | 商品ID | 顧客ID | 数量 | 金額 |
|---|---|---|---|---|---|
| 1 | 20240115 | P001 | C001 | 2 | 5,000 |
| 2 | 20240115 | P002 | C002 | 1 | 3,000 |
| 3 | 20240116 | P001 | C001 | 1 | 2,500 |
ポイント:日付ID、商品ID、顧客IDは「外部キー」で、それぞれのマスタテーブルを参照します。数量と金額は集計対象の「メジャー」です。
| 商品ID | 商品名 | カテゴリ | 単価 |
|---|---|---|---|
| P001 | iPhone 15 | スマートフォン | 2,500 |
| P002 | AirPods Pro | イヤホン | 3,000 |
| P003 | iPad Air | タブレット | 8,000 |
ポイント:商品IDは「主キー」で重複がありません。商品名やカテゴリは商品を説明する属性情報です。
| 顧客ID | 顧客名 | 地域 | 会員ランク |
|---|---|---|---|
| C001 | 山田太郎 | 東京都 | ゴールド |
| C002 | 佐藤花子 | 大阪府 | シルバー |
| C003 | 鈴木一郎 | 東京都 | ブロンズ |
| 日付ID | 年 | 月 | 日 | 曜日 | 祝日フラグ |
|---|---|---|---|---|---|
| 20240115 | 2024 | 1 | 15 | 月曜日 | 0 |
| 20240116 | 2024 | 1 | 16 | 火曜日 | 0 |
ポイント:日付テーブルは時系列分析に必須です。年、月、曜日などで自由にデータを切り分けられます。
ファクトとディメンションの見分け方
テーブルを見たときに、それがファクトなのかディメンションなのかを判断するための質問を紹介します。
| 質問 | ファクトテーブルの場合 | ディメンションテーブルの場合 |
|---|---|---|
| このデータを集計する? | はい(SUM、AVG、COUNTなど) | いいえ(集計対象ではない) |
| 行数はどのくらい? | 多い(数万〜数百万行) | 少ない(数十〜数千行) |
| データはどのくらい変わる? | 頻繁(日次で追加される) | 稀(マスタ情報は安定) |
| 主な内容は? | 数値データ(金額、数量) | 説明テキスト(名前、分類) |
| 一意のキーがある? | 外部キーが複数ある | 主キーが1つある |
🔗 3. リレーションシップの概念
リレーションシップとは
リレーションシップとは、テーブル同士を結びつける線(関係)のことです。この関係があることで、異なるテーブルのデータを組み合わせて分析できるようになります。
| できること | 具体例 |
|---|---|
| データの結合 | 売上テーブルの「商品ID」から、商品マスタの「商品名」を取得できる |
| フィルターの連動 | 「スマートフォン」を選ぶと、自動的にスマートフォンの売上だけが表示される |
| ドリルダウン | 「カテゴリ」→「商品」→「売上詳細」と階層を掘り下げられる |
| データの整合性 | 商品名を変更しても、売上データに自動的に反映される |
主キーと外部キー
リレーションシップを理解するには、「主キー」と「外部キー」の概念を押さえておく必要があります。
| 特徴 | 説明 |
|---|---|
| 定義 | テーブル内で各行を一意に識別するための列 |
| 重複 | 重複してはいけない(各値は1回だけ出現) |
| NULL | 空白(NULL)であってはいけない |
| 存在場所 | ディメンションテーブルに存在する |
| 具体例 | 商品マスタの「商品ID」、顧客マスタの「顧客ID」 |
| 特徴 | 説明 |
|---|---|
| 定義 | 他のテーブルの主キーを参照している列 |
| 重複 | 重複可能(同じ値が何度も出現してOK) |
| 参照先 | 参照先のテーブルに存在する値のみ使用可能 |
| 存在場所 | ファクトテーブルに存在する |
| 具体例 | 売上テーブルの「商品ID」「顧客ID」「日付ID」 |
| 商品マスタ(主キー側) | 売上テーブル(外部キー側) |
|---|---|
| 商品ID: P001(1回だけ) | 商品ID: P001(複数回出現可能) |
| 商品ID: P002(1回だけ) | 商品ID: P001 |
| 商品ID: P003(1回だけ) | 商品ID: P002 |
| – | 商品ID: P001 |
ポイント:商品マスタでは「P001」は1回しか出現しませんが、売上テーブルでは同じ商品が何度も売れるため「P001」が複数回出現します。
フィルターの伝播方向
リレーションシップには「方向」があります。これは、フィルターがどちらのテーブルに影響するかを決めます。
| 方向 | 動作 | 使用場面 |
|---|---|---|
| 単一方向(推奨) | ディメンション → ファクト | 通常のケース(99%はこれ) |
| 双方向 | ディメンション ↔ ファクト | 特殊なケースのみ(多対多など) |
具体例:商品マスタで「スマートフォン」を選ぶと、売上テーブルも自動的にスマートフォンの売上だけに絞り込まれます。これがフィルターの伝播です。
| 問題 | 説明 |
|---|---|
| パフォーマンス低下 | フィルター処理が複雑になり、クエリが遅くなる |
| あいまい性 | 意図しないフィルター結果になることがある |
| 循環参照のリスク | 複数の双方向があると循環エラーが起きやすい |
結論:特別な理由がない限り、単一方向(ディメンション→ファクト)を使用しましょう。
🔢 4. カーディナリティ
カーディナリティとは
カーディナリティとは、2つのテーブル間で1つのレコードが何個のレコードと関連するかを表す概念です。日本語では「多重度」や「濃度」とも呼ばれます。
| 種類 | 記号 | 説明 |
|---|---|---|
| 一対多 | 1:* または 1:N | 最も一般的。1つのディメンション行に対して、複数のファクト行 |
| 多対一 | *:1 または N:1 | 一対多の逆方向から見た形。実質同じ |
| 一対一 | 1:1 | 稀なケース。両方の行が1対1で対応 |
| 多対多 | *:* または N:N | 避けるべき。ブリッジテーブルで解決 |
一対多(1:*)リレーションシップ
最も一般的で、データモデルの基本となる関係です。ほとんどのケースでこの関係を使います。
| 関係 | 一側(ディメンション) | 多側(ファクト) |
|---|---|---|
| 商品と売上 | 1つの商品(iPhone 15) | 複数の売上レコード |
| 顧客と注文 | 1人の顧客(山田太郎) | 複数の注文履歴 |
| 日付と売上 | 1つの日付(2024/01/15) | その日の複数の売上 |
| 部署と社員 | 1つの部署(営業部) | 複数の社員 |
覚え方:ディメンション側が「1」、ファクト側が「多(*)」と覚えましょう。
一対一(1:1)リレーションシップ
稀なケースで、通常は1つのテーブルにまとめた方が効率的です。特別な理由がある場合のみ使用します。
| 使用ケース | 説明 |
|---|---|
| セキュリティ分離 | 機密情報(給与、個人情報)を別テーブルに分離して、アクセス制御する |
| パフォーマンス最適化 | 頻繁に使う列とそうでない列を分けて、読み込み速度を向上 |
| 外部システム連携 | 異なるシステムからのデータを別テーブルで管理 |
多対多(*:*)リレーションシップと解決方法
多対多の関係は、直接接続してはいけません。ブリッジテーブル(中間テーブル)を使って、2つの一対多に分解します。
| 観点 | 説明 |
|---|---|
| 状況 | 1人の学生は複数の授業を受講できる。1つの授業には複数の学生が参加する。 |
| 問題 | 学生テーブルと授業テーブルを直接つなぐと、どの学生がどの授業を受けているかわからない |
| 解決策 | 「履修テーブル」というブリッジテーブルを作成する |
変換前:学生 *:* 授業(多対多)
変換後:学生 1:* 履修 *:1 授業(2つの一対多)
| 履修ID | 学生ID | 授業ID | 成績 |
|---|---|---|---|
| 1 | S001 | L001 | A |
| 2 | S001 | L002 | B |
| 3 | S002 | L001 | A |
| 4 | S002 | L003 | C |
ポイント:履修テーブルは「どの学生が」「どの授業を」受けているかを記録し、成績などのメジャーも持てます。
📐 5. 正規化と非正規化
正規化とは
正規化とは、データの重複をなくすためにテーブルを分割することです。同じ情報を何度も保存しないようにします。
| 売上ID | 日付 | 商品名 | カテゴリ | 単価 | 数量 | 金額 |
|---|---|---|---|---|---|---|
| 1 | 2024/01/15 | iPhone 15 | スマホ | 2,500 | 2 | 5,000 |
| 2 | 2024/01/15 | AirPods | イヤホン | 3,000 | 1 | 3,000 |
| 3 | 2024/01/16 | iPhone 15 | スマホ | 2,500 | 1 | 2,500 |
問題点:「iPhone 15」「スマホ」「2,500」が何度も出現。データサイズが大きく、商品情報を変更するには全行を更新する必要がある。
【売上テーブル】
| 売上ID | 日付ID | 商品ID | 数量 | 金額 |
|---|---|---|---|---|
| 1 | 20240115 | P001 | 2 | 5,000 |
| 2 | 20240115 | P002 | 1 | 3,000 |
| 3 | 20240116 | P001 | 1 | 2,500 |
【商品マスタ】
| 商品ID | 商品名 | カテゴリ | 単価 |
|---|---|---|---|
| P001 | iPhone 15 | スマホ | 2,500 |
| P002 | AirPods | イヤホン | 3,000 |
メリット:データ重複なし、サイズ小、商品情報は1箇所で管理、整合性が保たれる。
| 観点 | メリット | デメリット |
|---|---|---|
| データサイズ | 重複がなく小さい | テーブル数が増える |
| 整合性 | 1箇所変更で全体に反映 | リレーションシップの設定が必要 |
| パフォーマンス | メモリ効率が良い | 過度な正規化はクエリが遅くなる |
| 理解しやすさ | データ構造が明確 | 複雑すぎると把握が難しい |
| 推奨度 | 説明 |
|---|---|
| ✅ 推奨 | ファクトとディメンションに分ける程度の「適度な正規化」 |
| ❌ 避ける | 完全な正規化(第3正規形など)は不要。テーブルが多すぎると逆効果 |
| ❌ 避ける | 非正規化(すべて1つのテーブル)も避ける。重複が多く非効率 |
結論:「スタースキーマ」(1つのファクト+複数のディメンション)が最もバランスの良い設計です。
🎨 6. 良いデータモデルの設計原則
スタースキーマとは
Power BIで最も推奨されるデータモデルは「スタースキーマ」です。中心にファクトテーブル、その周りにディメンションテーブルを配置し、星(スター)のような形になります。
| 位置 | テーブルの種類 | 説明 |
|---|---|---|
| 中心 | ファクトテーブル(1つ) | 数値データ(売上、数量など)を格納 |
| 周囲 | ディメンションテーブル(複数) | 商品、顧客、日付などのマスタデータ |
| 接続 | リレーションシップ | 1対多の関係でファクトとディメンションを結ぶ |
なぜスタースキーマ?シンプルで理解しやすく、Power BIの最適化エンジンと相性が良いため、パフォーマンスが向上します。
データモデル設計の7原則
良いデータモデルを設計するために、以下の原則を守りましょう。
| No. | 原則 | 説明 |
|---|---|---|
| 1 | スタースキーマを採用 | 1つのファクトテーブルを中心に、複数のディメンションテーブルを配置 |
| 2 | 明確なキーを設定 | 主キーは一意で重複なし、外部キーは参照先に存在する値のみ |
| 3 | 適切な粒度を決める | ファクトテーブルの詳細レベル(日次、月次など)を明確に |
| 4 | 日付テーブルを作成 | 時系列分析には専用の日付ディメンションが必須 |
| 5 | 単一方向フィルター | ディメンション→ファクトの一方向フィルターを基本とする |
| 6 | ディメンションの重複排除 | ディメンションテーブルの主キーに重複があってはならない |
| 7 | 適切なデータ型 | 数値は数値型、日付は日付型、IDはテキスト型など |
避けるべきアンチパターン
以下のような設計は問題を引き起こすため、避けましょう。
| アンチパターン | 問題点 | 対策 |
|---|---|---|
| 循環参照 | A→B→C→Aのような輪ができる | 不要なリレーションシップを削除 |
| 多対多の直接接続 | ブリッジテーブルなしで接続 | 中間テーブルを作成して分解 |
| 非正規化しすぎ | すべて1つのテーブルにまとめる | ファクトとディメンションに分離 |
| 正規化しすぎ | テーブルが多すぎて複雑 | スタースキーマ程度に抑える |
| 日付がテキスト型 | 日付型を使わない | 日付列は必ず日付型に変換 |
| 計算列の乱用 | メジャーで代用可能なものを計算列に | 集計はメジャーで行う |
パフォーマンス最適化のポイント
大量のデータを扱う場合、以下のポイントを意識するとパフォーマンスが向上します。
| 最適化ポイント | 理由 | 効果 |
|---|---|---|
| ファクトをシンプルに | 必要な列のみにする | メモリ使用量削減 |
| 不要な列を削除 | 使わない列は読み込まない | 読み込み時間短縮 |
| 適切なデータ型 | 整数 < 10進数 < テキスト(メモリ順) | メモリ効率向上 |
| 不要なリレーション削除 | 使わない関係は消す | クエリ処理高速化 |
| 双方向フィルター最小限 | 本当に必要な場合のみ | 計算の複雑さ軽減 |
| ディメンションの重複なし | 重複があると集計がおかしくなる | 正確な集計結果 |
📝 STEP 32 のまとめ
- データモデル: テーブル間の関係を定義した「設計図」
- ファクトテーブル: 数値データを格納するトランザクションテーブル
- ディメンションテーブル: 説明情報を格納するマスタテーブル
- リレーションシップ: 主キーと外部キーでテーブルを結合
- カーディナリティ: 1対多(1:*)が基本
- 正規化: 適度に分割して重複を避ける
- スタースキーマ: 中心にファクト、周囲にディメンション
良いデータモデルは分析の成否を決める基盤です。
基本はスタースキーマ:中心に1つのファクトテーブル、周りに複数のディメンションテーブル。
1対多のリレーションシップで結ぶ。
これだけ覚えれば、ほとんどのケースに対応できます!
📝 実践演習
Power BI Desktopでサンプルデータを読み込み、モデルビューを開いてください。テーブルを観察し、どのテーブルがファクトで、どのテーブルがディメンションか識別してください。
| 1 | Power BI Desktopを起動 |
| 2 | サンプルデータ(財務サンプルなど)を読み込む |
| 3 | 左サイドバーの「モデルビュー」(🔗アイコン)をクリック |
| 4 | テーブルを観察し、列の内容を確認 |
💡 識別のポイント:
- ファクトテーブル:数値列が多い(金額、数量など)、行数が多い、外部キーを持つ
- ディメンションテーブル:テキスト列が多い(名前、カテゴリなど)、行数が少ない、主キーを持つ
リレーションシップの確認:線をダブルクリックすると、どの列同士が結ばれているか、カーディナリティ(1と*)が表示されます。
以下のビジネスシナリオに適したデータモデルを設計してください:「オンラインショップで、顧客が商品を購入する。各商品はカテゴリに属し、各注文には日付がある。」ファクトとディメンションを分けて、テーブル構造を考えてください。
ファクトテーブル:注文明細
| 列名 | データ型 | 説明 |
|---|---|---|
| 注文明細ID | 整数 | 主キー |
| 日付ID | 整数 | 外部キー→日付テーブル |
| 商品ID | テキスト | 外部キー→商品テーブル |
| 顧客ID | テキスト | 外部キー→顧客テーブル |
| 数量 | 整数 | メジャー |
| 金額 | 10進数 | メジャー |
ディメンションテーブル:商品マスタ、顧客マスタ、日付マスタ、カテゴリマスタ
リレーションシップ:
- 商品マスタ(1)→(*)注文明細
- 顧客マスタ(1)→(*)注文明細
- 日付マスタ(1)→(*)注文明細
- カテゴリマスタ(1)→(*)商品マスタ
多対多の関係を解決してください:「学生は複数の授業を履修でき、1つの授業には複数の学生が参加する。」ブリッジテーブルを使って1対多の関係に分解し、テーブル構造を設計してください。
元の問題:学生 *:* 授業(多対多)
解決後:学生 1:* 履修 *:1 授業(2つの一対多)
テーブル1:学生マスタ(ディメンション)
| 列名 | 説明 |
|---|---|
| 学生ID(主キー) | S001, S002, … |
| 学生名 | 山田太郎, 佐藤花子, … |
| 学年, 学部 | 属性情報 |
テーブル2:授業マスタ(ディメンション)
| 列名 | 説明 |
|---|---|
| 授業ID(主キー) | L001, L002, … |
| 授業名 | データ分析入門, … |
| 担当教員, 単位数 | 属性情報 |
テーブル3:履修テーブル(ブリッジテーブル/ファクト)
| 列名 | 説明 |
|---|---|
| 履修ID(主キー) | 1, 2, 3, … |
| 学生ID(外部キー) | 学生マスタを参照 |
| 授業ID(外部キー) | 授業マスタを参照 |
| 成績, 出席率 | メジャー |
💡 ポイント:
- 履修テーブルがブリッジテーブルとして機能
- 多対多を2つの1対多に分解
- 履修テーブルは成績などのメジャーも持てる
❓ よくある質問
1つのテーブルだと、以下の問題が発生します:
- データが重複し、メモリを大量消費
- 商品名を変更するには全行を更新する必要がある
- データの整合性が保ちにくい
ファクトとディメンションに分けた方が、パフォーマンスとメンテナンス性が向上します。
例えば、「売上」と「在庫」は別々のファクトテーブルとして管理できます。複数のファクトテーブルがあっても、共通のディメンション(商品、日付など)で結ぶことで、統合的な分析が可能です。
ただし、初心者はまず1つのファクトテーブルから始めることをおすすめします。
日付テーブルがあると:
- 年、月、四半期、曜日などで簡単に分析できる
- Power BIの「日付テーブルとしてマーク」機能が使える
- タイムインテリジェンス関数(前年比較など)が使える
Power BIは自動で日付テーブルを作成しますが、カスタム日付テーブルを作成する方がより柔軟な分析が可能です。
テーブルA→B→C→Aのような循環を作ってはいけません。
対処法:
- モデルビューでリレーションシップの線を確認
- 不要なリレーションシップを削除
- または、1つのリレーションシップを「非アクティブ」に設定
Power BIは多対多のリレーションシップをサポートしていますが、以下の問題があります:
- 意図しない集計結果になることがある
- DAX式が複雑になる
- パフォーマンスが低下する可能性
推奨:ブリッジテーブルを作成して、2つの1対多に分解しましょう。
例えば、商品マスタに「P001」が2行あると、その商品の売上が2倍にカウントされてしまいます。
対処法:
- Power Queryで「重複の削除」を実行
- 元データの品質を確認
- 列の品質表示で重複を検出
| 項目 | スタースキーマ | スノーフレークスキーマ |
|---|---|---|
| 構造 | ファクト+ディメンション | ファクト+ディメンション+サブディメンション |
| 複雑さ | シンプル | 複雑 |
| Power BIでの推奨 | 推奨 | 非推奨(必要な場合のみ) |
Power BIではスタースキーマの方がパフォーマンスが良いため、基本はスタースキーマを使いましょう。
学習メモ
BIツール入門 - Step 32