Default Row は、[[ファクトテーブル]] の外部キーが参照先を持たないときの受け皿として、ディメンションテーブルへあらかじめ挿入しておく特殊な行である。サロゲートキーに予約値を割り当て、属性には「Unknown」のような読めるラベルを入れる。 この手法は [[ディメンショナルモデリング]] の設計テクニックの 1 つで、外部キーの NULL を禁止する原則を支える。NULL のまま内部結合するとファクト行が静かに消えるため、NULL の代わりに振れる参照先をディメンション側へ用意しておく。 > [!info] > 原典は『[[The Data Warehouse Toolkit]]』(3rd Edition) 3 章の "Null Foreign Keys, Attributes, and Facts" 項。 > > Kimball Group の [Selecting Default Values for Nulls](https://www.kimballgroup.com/2010/10/design-tip-128-selecting-default-values-for-nulls/) テクニックとして紹介されている。 > [!note] > Adamson の『[[Star Schema The Complete Reference]]』は、同じ行を special-case row と呼んで最も体系的に解説している (Ch.6「Avoiding the NULL」節群)。 > > 文献によって呼び名は揺れるが、本サイトでは Default Row で統一する。 ## 役割 外部キーの NULL を禁止する原則を守るには、NULL だった行の振り先が要る。Default Row はその振り先として、ディメンションテーブルに次のような行を用意する。 ``` dim_user | user_key (SK) | user_id (NK) | user_name | | ------------- | ------------ | --------- | | 0 | NULL | (Unknown) | <-- Default Row | 1 | usr-001 | Sato | | 2 | usr-002 | Suzuki | fct_order | order_key (SK) | user_key (FK) | order_id (DD) | order_amount (FA) | | -------------- | ------------- | ------------- | ----------------- | | 1 | 1 | odr-001 | 1200 | | 2 | 2 | odr-002 | 3400 | | 3 | 1 | odr-003 | 560 | | 4 | 0 | odr-004 | 2200 | <-- Default Row を参照 | 5 | 2 | odr-005 | 900 | | 6 | 0 | odr-006 | 1200 | <-- Default Row を参照 ``` 参照先を持たないファクト行の外部キーには、NULL の代わりに予約キー 0 を振る。これで外部キーが必ずディメンションのどれかの行に当たり、内部結合でも外部結合でも集計結果が一致する。 > [!note] > ラベルを `(Unknown)` と括弧で囲むのは、ソースの正規値と DWH 側の埋め値を見分けるためである。文字コード順で先頭に寄るため、レポートでのソート位置も安定する。 受け皿は 1 行とは限らない。ゲスト購入のように NULL の原因を判別できるなら原因ごとの行を追加し、先の例で 0 を振ったゲスト注文は -1 で受け直す。0 は原因を判別できない行のために残る。 ``` dim_user | user_key (SK) | user_id (NK) | user_name | | ------------- | ------------ | ---------------- | | 0 | NULL | (Unknown) | <-- Default Row | -1 | NULL | (Not Applicable) | <-- Default Row | 1 | usr-001 | Sato | | 2 | usr-002 | Suzuki | ``` ## 関連ノート - **[深掘り]** [[スタースキーマの NULL 可否は列の役割で決める]]: 本ノートで触れた NULL 放置の壊れ方を、SQL の実演で確かめられる - **[深掘り]** [[Default Row の行数は NULL の原因をどこまで区別するかで決める]]: 原因ごとに行を分けるとき、どこまで区別するかの判断軸