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 の原因をどこまで区別するかで決める]]: 原因ごとに行を分けるとき、どこまで区別するかの判断軸