[[ディメンションテーブル]] の中に置く日付属性 (登録日・生年月日など) は、プレーンな DATE 列をデフォルトにする。日付ディメンションへの外部キー (アウトリガー) にするのは、カレンダー属性で絞り込む要件があるときに限る例外である。 ```mermaid erDiagram dim_user ||--o{ fct_order : "user_key" dim_date ||--o{ fct_order : "order_date_key" fct_order { user_key int64 "[FK] ユーザーキー" order_date_key int64 "[FK] 注文日キー" order_amount int64 "[FA] 注文金額" } dim_user { user_key int64 "[SK] ユーザーキー" user_id string "[NK] ユーザーID" registered_date date "登録日" birth_date date "生年月日" } dim_date { date_key int64 "[PK] 日付キー" full_date date "日付 (yyyy-mm-dd)" fiscal_year string "会計年" holiday_name string "祝日名" } ``` > [!info] > 原典は『[[The Data Warehouse Toolkit]]』(3rd Edition) 3 章 "Retail Sales" の Outriggers 項。Kimball Group の [Outrigger Dimensions](https://www.kimballgroup.com/data-warehouse-business-intelligence-resources/kimball-techniques/dimensional-modeling-techniques/outrigger-dimension/) テクニックとしても解説されている。 ## 例外: アウトリガーへの昇格 会計期間・祝日などのカレンダー属性で絞り込む要件が出たときに限り、元の DATE 列を残したまま日付ディメンションへの外部キーを追加する。参照先は列名を役名で変えた論理的なコピー、つまりロールプレイングされた日付ディメンションになる。 ```mermaid erDiagram dim_user ||--o{ fct_order : "user_key" dim_date ||--o{ fct_order : "order_date_key" dim_date ||--o{ dim_user : "registered_date_key" fct_order { user_key int64 "[FK] ユーザーキー" order_date_key int64 "[FK] 注文日キー" order_amount int64 "[FA] 注文金額" } dim_user { user_key int64 "[SK] ユーザーキー" user_id string "[NK] ユーザーID" registered_date date "登録日" registered_date_key int64 "[FK] 登録日キー" birth_date date "生年月日" } dim_date { date_key int64 "[SK] 日付キー" full_date date "日付 (yyyy-mm-dd)" fiscal_year string "会計年" holiday_name string "祝日名" } ``` > [!note] > 原典はこの構造を「許容されるが、規則ではなく例外であるべき (permissible, but they should be the exception rather than the rule)」と位置づけている。 この判断は、手に入る属性と結合コストのトレードオフで説明できる。年や月なら DATE 列から SQL の日付関数で導出できるため、アウトリガーは要らない。一方、会計期間や祝日は暦の規則から計算できず、日付ディメンションを結合しないと手に入らない。 導出できない属性が要件になった時点で初めて、結合が増えてスキーマがスノーフレーク化するコストを払う価値が生まれる。 ## 関連ノート - **[派生]** [[スタースキーマの NULL 可否は列の役割で決める]]: 日付属性が例外的に NULL を許容するという線引きの出どころ