04

データモデリングと設計

Data Modelling & Design — DAMA-DMBOK Ch.5

11%
★ 最重要
← メインに戻る
モデリング3層(CDM / LDM / PDM)
最上位 — 抽象
概念モデル
Conceptual Data Model (CDM)
対象: ビジネスステークホルダー
  • エンティティ名・関係のみ
  • 技術的詳細なし
  • ビジネス語彙・概念を反映
  • 例: 顧客 ↔ 注文 ↔ 製品
中間 — 論理
論理モデル
Logical Data Model (LDM)
対象: データアーキテクト・アナリスト
  • すべての属性を含む
  • データ型・長さを定義
  • 正規化 (1NF〜3NF) 適用
  • 特定DBMS非依存
最下位 — 具体
物理モデル
Physical Data Model (PDM)
対象: DBA・開発者
  • 特定DBMSに最適化
  • テーブル・インデックス・制約
  • 意図的な非正規化
  • パーティション・ストレージ設定
試験ポイント: 「概念モデルの対象者はビジネスステークホルダー」「論理モデルは特定DBMSに依存しない」「物理モデルはDBMS固有の実装を含む」の3点が頻出。
正規化(Normalization)— 1NF → BCNF
1NF
第1正規形
繰り返しグループなし
すべての値が原子値(分割不可能)
2NF
第2正規形
1NF + 部分関数従属の除去
複合キーの一部のみへの依存を排除
3NF
第3正規形
2NF + 推移的関数従属の除去
非キー→非キーの依存を排除
BCNF
ボイスコッド正規形
3NF + すべての決定子が
候補キーである
正規形解消する問題キーワード
1NF 繰り返しグループ・非原子値 Atomic values / 原子値
2NF 部分関数従属(複合キーの一部への依存) Partial Dependency
3NF 推移的関数従属(非キー→非キー依存) Transitive Dependency
BCNF 全決定子が候補キーでない問題 Candidate Key / Determinant
4NF 多値従属(Specialist対象) Multi-valued Dependency
試験注意: Fundamentals試験は1NF〜3NF/BCNFを中心に出題。4NF/5NFはSpecialist対象。
ERDとUMLの表記法
記号意味読み方
||1(必須)Exactly One
|O0 または 1(オプション)Zero or One
}|1以上(必須・多)One or Many
}O0以上(オプション・多)Zero or Many
記法別名特徴
IE記法Crow's Foot最も一般的。鳥の足で「多」を表現
バーカー記法Barker / OracleOracle社方式。ソフトライン使用
Chen記法ERDの原型ダイヤモンドが関係を表す
UML クラス図オブジェクト指向設計と整合
スタースキーマ vs スノーフレークスキーマ
★ スタースキーマ(非正規化ディメンション)
FACT sales_fact amount, qty dim_date year,month,day... dim_customer name,addr,seg dim_product name,cat,brand dim_channel online,store...
ディメンション = 非正規化・シンプル・高速クエリ
❄ スノーフレークスキーマ(正規化ディメンション)
FACT amount, qty dim_product name, cat_id dim_category cat_id, name dim_date date_id, month_id dim_month month_id, year dim_customer id, pref_id dim_pref pref_id, name
ディメンション = 正規化・整合性高・JOINが多く複雑
観点スタースキーマスノーフレークスキーマ
ディメンション非正規化(フラット)正規化(階層的)
クエリ性能高速(JOINが少ない)やや遅い(JOINが多い)
データ整合性冗長データあり高い
ストレージやや多い節約できる
設計の複雑さシンプル複雑
SCD(Slowly Changing Dimension)Type 1 / 2 / 3
タイプ対処法履歴使いどき実務例
Type 1 上書き(既存レコードを更新) なし 誤り訂正・過去は気にしない 電話番号の誤入力修正
Type 2 新行追加 + 有効日付で管理 完全保持 完全な変更履歴が必要 顧客住所変更(地域別分析)
Type 3 カラム追加(前値・現値を同行に保持) 限定的 変更前後の比較のみ必要 部門変更(現在と直前のみ)
Type 2 の必須カラム: effective_from_dt(開始日)/ effective_to_dt(終了日、NULLが現在有効)/ is_current_flag
正規化 vs 非正規化 — トレードオフ
観点正規化(3NF)非正規化
データ整合性高い(更新異常なし)リスクあり(重複データ)
読み取り性能JOINが多く遅くなりやすい高速(JOINが少ない)
書き込み性能効率的冗長な更新が必要
ストレージコンパクト冗長で大きい
用途OLTP(トランザクション処理)OLAP(分析・DWH)
設計原則論理モデル(整合性優先)物理モデル(パフォーマンス優先)
キー設計
種類説明利点欠点
ナチュラルキー ビジネス上の意味を持つキー
例: 社員番号、マイナンバー
意味が明確・人間が読める ビジネスルール変更でキー変更が必要
サロゲートキー システムが生成する意味のないキー
例: ID = 1, 2, 3 / UUID
安定・変更に強い・外部キー結合が簡潔 ビジネス的な意味なし
DWH設計原則: サロゲートキーをDWH用PKとして使い、ナチュラルキーはNATURAL_ID列として別途保持(SCD Type 2 で必須)。
★ Specialist 深掘りセクション
次元説明
完全性全ビジネス概念がモデル化されているか
正確性ビジネスルールが正確に表現されているか
一貫性命名規則・データ型・パターンが統一されているか
簡潔性冗長な要素がないか(過剰設計を避ける)
安定性ビジネス変化に対して変更しやすい設計か
要素役割
Hubビジネスキーを格納
customer_hub → customer_natural_id
LinkHub間の関係を格納
order_customer_link
Satellite属性・全変更履歴を格納
customer_name_sat(追記のみ)
利点: 監査性が高い / アジャイルなスキーマ変更 / 並列ロード容易
適した場面: 銀行・保険など監査要件が厳しい業務
Valid Time(有効時間)
ビジネス上の事実が真であった期間
例: 顧客が東京に住んでいた期間
Transaction Time(取引時間)
DBにレコードが存在した期間
例: このデータがDBに登録・更新された日時
-- Bi-temporal テーブル(両方の時制を管理)
CREATE TABLE customer_bitemporal (
    customer_id       INT,
    name              VARCHAR(100),
    -- Valid Time
    valid_from        DATE,        -- この情報がビジネス上いつから有効か
    valid_to          DATE,        -- この情報がビジネス上いつまで有効か
    -- Transaction Time
    recorded_at       DATETIME,    -- DBにいつ書き込まれたか
    superseded_at     DATETIME     -- この行がいつ上書きされたか(NULLは現在)
);
変更要求
Change Request
影響分析
Impact Analysis
ステークホルダー
レビュー
Business + Technical
承認・実装
+ バージョン管理
アンチパターン: 開発者がモデルを勝手に変更してからDBを変更する → ガバナンス違反。モデルが「設計図」として機能するには変更プロセスが必須。
3層モデル比較(CDM / LDM / PDM)
概念モデル (CDM) 論理モデル (LDM) 物理モデル (PDM)
対象者ビジネスステークホルダーデータアーキテクト・アナリストDBA・開発者
含む内容エンティティ・関係のみ属性・データ型・正規化テーブル・インデックス・制約
DBMS依存なしなし(DB非依存)あり(DBMS固有)
正規化不適用1NF〜3NF適用意図的に非正規化も
目的ビジネス合意形成設計の論理的整合性パフォーマンス最適化
キーワードEntity / RelationshipAttribute / NormalizationTable / Index / Partition
SCD タイプ比較(1 / 2 / 3)
タイプ方法履歴保持追加カラム例使う場面
Type 1 既存行を上書き(UPDATE) なし 不要 誤入力訂正・過去不要
Type 2 新行を追加(INSERT) 完全 effective_from, effective_to, is_current 住所変更・セグメント変更
Type 3 カラムを追加(ALTER TABLE) 限定的 prev_address, current_address 変更前後の比較のみ
最頻出: SCD Type 2 — 「有効開始日・有効終了日・現在フラグの3点セット」を覚える。
正規化ルール早見表
正規形前提追加条件除去する依存関係
1NF原子値・繰り返しグループなし非原子値・繰り返し
2NF1NF部分関数従属の除去A,B → C で A → C となる部分依存
3NF2NF推移的関数従属の除去PK → X → Y の間接依存
BCNF3NF全決定子が候補キー候補キー以外の決定子
スター vs スノーフレーク — 瞬時判別
★ スタースキーマ
  • • ディメンション = 非正規化(フラット)
  • • JOINが少ない → クエリ高速
  • • シンプルな星型構造
  • • Kimball DWH の標準手法
❄ スノーフレークスキーマ
  • • ディメンション = 正規化(階層的)
  • • JOINが多い → 整合性高い
  • • 雪の結晶のような複雑構造
  • • ストレージ効率が良い
頻出キーワード一覧
キーワード定義
ナチュラルキービジネス上の意味を持つキー(変更リスクあり)
サロゲートキーシステム生成の意味なし識別子(安定)
候補キー行を一意に識別できる最小の属性集合
スーパーキー候補キーを含む任意の属性集合
外部キー他テーブルの主キーを参照する属性
キーワード定義
Forward Engineering要件→概念→論理→物理→DDL生成
Reverse Engineering既存DB→物理→論理→文書化
ファクトテーブル数値指標+ディメンションキー(DWH中心)
ディメンションテーブル分析軸(日時・顧客・製品)の詳細情報
EAVEntity-Attribute-Value(アンチパターン)
スコア: 0 / 0 問回答
Case 1: EC企業の注文データモデル設計
背景

日本の中規模ECプラットフォーム(月間注文数100万件)。初期モデルに以下の問題が発生:

  • • キャンペーン価格・通常価格・会員価格が混在し「注文時点の価格」が追跡不可
  • • 商品属性をEAVパターンで管理(アンチパターン)
  • • 返品・交換処理が元設計と整合しない
アンチパターン: EAV(Entity-Attribute-Value)
CREATE TABLE product_attributes (
    product_id    INT,
    attr_name     VARCHAR(100),  -- 'size', 'color', 'weight' etc.
    attr_value    VARCHAR(500)
);
EAVの問題点(試験で問われる):
• データ型の制御不可(数値も文字列として格納)
• 特定属性での検索が極端に遅い
• 外部キー制約・NOT NULL制約が使えない
• 正規化の観点で1NFすら満たさない場合がある
-- OrderHeader(注文ヘッダー)
order_id (PK, Surrogate), customer_id (FK), order_datetime,
order_status_cd (FK → OrderStatus), channel_cd (FK → SalesChannel)

-- OrderLine(注文明細)— 注文時価格を記録!
order_line_id (PK, Surrogate), order_id (FK), product_variant_id (FK),
quantity, unit_price_at_order, discount_amount, list_price_at_order

-- ProductVariant(商品バリアント)
variant_id (PK, Surrogate), product_id (FK), size_cd, color_cd, sku

-- Product(商品マスタ)
product_id (PK, Surrogate), product_name, category_id (FK), base_price
CREATE TABLE order_line (
    order_line_id         BIGINT PRIMARY KEY,
    order_id              BIGINT NOT NULL,
    product_variant_id    INT    NOT NULL,
    quantity              INT    NOT NULL,
    unit_price_at_order   DECIMAL(10,2) NOT NULL,
    -- 意図的な非正規化(JOINコスト削減)
    product_name_snapshot VARCHAR(200),  -- 注文時の商品名スナップショット
    variant_desc_snapshot VARCHAR(100),  -- 注文時のバリアント説明
    INDEX idx_order_id (order_id),
    INDEX idx_created (created_at)
) PARTITION BY RANGE (YEAR(created_at));  -- 年次パーティション
設計原則: 論理モデルは3NF(整合性優先)、物理モデルは意図的な非正規化(パフォーマンス優先)
Case 2: SCD Type 2 の完全実装
背景

DWHの顧客ディメンション設計。顧客の住所が変わった場合に「以前の住所での注文」と「新住所での注文」を正確に分析したい。

CREATE TABLE dim_customer (
    customer_key         INT PRIMARY KEY,           -- Surrogate Key(DWH用)
    customer_natural_id  VARCHAR(20) NOT NULL,   -- ナチュラルキー(元システムID)
    customer_name        VARCHAR(100),
    address_line1        VARCHAR(200),
    prefecture_cd        CHAR(2),
    -- SCD Type 2 制御カラム(3点セット)
    effective_from_dt    DATE NOT NULL,              -- この行が有効になった日
    effective_to_dt      DATE,                      -- NULL = 現在有効
    is_current_flag      CHAR(1) DEFAULT 'Y',      -- 現在有効行フラグ
    dw_created_dt        DATETIME,
    source_system_cd     VARCHAR(10)
);
-- 現在の顧客情報
SELECT * FROM dim_customer
WHERE is_current_flag = 'Y';

-- 特定日時点のデータ
SELECT * FROM dim_customer
WHERE customer_natural_id = 'C001'
  AND effective_from_dt <= '2023-06-15'
  AND (effective_to_dt > '2023-06-15'
       OR effective_to_dt IS NULL);
落とし穴 1
effective_to_dt にNULLと '9999-12-31' が混在 → クエリが複雑化
落とし穴 2
複数レコードで is_current_flag='Y' が付く(ETL冪等性の欠如)
落とし穴 3
ナチュラルキーにインデックスがない → 全履歴検索が遅い
Type使いどき実務例
Type 1誤り訂正・過去は気にしない電話番号の誤入力修正
Type 2完全な変更履歴が必要顧客住所変更(地域別分析)
Type 3変更前後の比較のみ部門変更(現在と1つ前)
Type 4履歴を別テーブルに分離急速に変わる属性(価格等)
Type 6Type 1+2+3 組み合わせ複雑なケース(Kimball推奨)
試験注意: Type 4, 5, 6 はFundamentals試験には出ない。DW&BI Specialist試験で出題。
Case 3: アンチパターン診断
アンチパターン 1: God Table(神テーブル)
-- 500カラム以上、あらゆるデータが1テーブルに
CREATE TABLE customer_all (
    id           INT PRIMARY KEY,
    name         VARCHAR(100),
    address      VARCHAR(500),
    -- ... 497カラム続く
    order_count  INT,       -- 集計値が入ってる!
    last_order_date DATE   -- 集計値が入ってる!
);
問題: NULLが多発 / 集計値が整合性を崩す / スパースデータのストレージ浪費
正しい対処
正規化してサブタイプに分離(Individual / Corporate)+ 集計値はViews or 集計テーブルに切り出す
アンチパターン 2: 意味のある複合主キー
CREATE TABLE order_item (
    order_id      INT,
    product_code  VARCHAR(20),
    PRIMARY KEY (order_id, product_code)  -- ビジネスキー組み合わせをPKに
);
問題: product_code体系変更でPK変更が必要 / カスケードアップデートが発生
正しい対処
サロゲートキーをPKとし、業務キーはUNIQUE制約で保証
アンチパターン 3: 汎用ステータステーブル
CREATE TABLE statuses (
    entity_type   VARCHAR(50),  -- 'order', 'customer', 'product'
    status_code   VARCHAR(20),
    status_name   VARCHAR(100)
);
問題: 外部キー制約が貼れない / entity_typeで絞り込まないと不正参照が可能
正しい対処
エンティティごとに独立したステータステーブル(order_status, customer_status)
Case 4: データモデルレビューの実施
1
ビジネス要件との整合性
全ビジネス概念がモデルに存在するか / ビジネスルールが制約として表現されているか / ビジネスユーザーが概念を認識できるか
2
データ整合性
参照整合性が保証されているか / NOT NULL・CHECK制約が適切か / CASCADEの動作は意図通りか
3
設計の一貫性
命名規則が統一されているか(PascalCase/snake_case)/ データ型が一貫しているか / パターンが統一されているか
4
パフォーマンス考慮
高頻度クエリのインデックスが適切か / N+1問題が発生しうる設計か / パーティショニングが必要か
☐ エンティティ定義がBusiness Glossaryと一致
☐ 必須属性に NOT NULL が設定されている
☐ 外部キーにはインデックスが存在する
☐ 命名規則ドキュメントに準拠している
☐ SCDタイプの選択理由が文書化されている
☐ ビジネスステークホルダーのレビュー完了
☐ バージョン管理システムにモデルが保存
★ Specialist 試験 頻出シナリオ問題
問題 1
小売業DWHチームが顧客セグメント変更(Gold→Silver等)を追跡。変更前後の双方で売上集計したい。最適なSCDタイプは?
解答
SCD Type 2 — 新行追加で履歴を保持。Type 3では直前の変更しか追えない。Type 1では履歴が消える。
問題 2
製品バリアント(サイズ×カラー)の属性設計でEAVパターンを提案されたが、バリアントごとに属性数が異なる。何を推奨するか?
解答
EAVは避ける。ProductType別サブタイプテーブル、またはJSONカラムのhybridアプローチ。EAVは検索・制約・型安全性の全てで劣る。
問題 3
Reverse Engineeringの主な目的は何か?
解答
既存DBから論理・概念データモデルを再構築し文書化すること。レガシーシステムの理解、移行計画、コンプライアンス対応に使用。