DWHにおける時間性(Temporality)第2部:時間的複雑性の排除
Data Vaultにおける時間的複雑性をいかに排除・簡素化するか。2d属性化、テンポラル・インスタンス・ハブ、トランザクションへの属性インスタンス化という3大戦略を解説。
Data Vaultにおける「時間性(Temporality)」の取り扱い
時間的複雑性を排除するアプローチ
DWH自動化ソフトウェア「Datavault Builder」の開発元として、私たちは「ツール内やData Vault一般において、時間の経過に伴うデータ変更をどのように正しくモデル化すべきか」というご質問を頻繁にいただきます。多くの場合、「SCD Type 2のデータをどのようにレポート出力すればよいか」という形です。しかし、議論している時間軸がどの軸を指しているのかが曖昧なことが少なくありません。そこで本記事では、この複雑な時間性の整理を試みます。
本記事は連載の第2部です:
- 第1部:DWHにおける時間性の定義と直面する課題
- 本記事(第2部):時間的な複雑性を極力シンプルに抑え込むための具体策
- 第3部:どのようなビジネス要件において複数時間軸の出力が必要になるのか
- 第4部:技術的に3dタイムラインをSCD Type 2として出力する方法
Data Vaultにおける時間性の扱いには複数のアプローチが存在します(Dirk Lerner氏、Christian Kaul氏、Lars Rönnbäck氏の著作も強く推奨します)。ここでは、複雑な時間軸を制御可能なレベルに単純化・整理する実践的なアプローチを提示します。
第1部で定義した通り、本稿では以下の3つの時間軸に絞って議論します:
- 1d: 業務有効時間(Valid Time)
- 2d: 登録時刻(Inscription Time)
- 3d: DWHロード日時(Load Time)
第1の次元(1d)はビジネス上の有効性です。このタイムラインの特性は、「新しいタイムスライスが追加されても、古いエントリが無効になるわけではない」という点にあります。筆者がチューリッヒからバーゼルへ転居したとしても、「かつてチューリッヒに住んでいた」という過去の事実は間違いではありません(注1)。将来の転居先を事前登録した場合でも、現時点で有効な住所情報は何ら変わりません。つまり、異なる時点で現在形であった複数の情報が存在しますが、それらはすべて真実であり有効(Valid)なのです。
1d軸:すべての情報は有効であるが、現時点でカレントなのは1つのエントリのみ。
第2の次元(2d)はソースシステムへの登録時刻です。1d軸においては未来の日付や過去の訂正を事後入力できるため、この2d軸が重要になります。業界や部門によっては、これが不正(架空契約の登録と事後削除による営業インセンティブの詐取など)の温床になり得ます。したがって、監査や不正検知には2dが極めて重要ですが、日常の定常レポーティングでは無視できるケースがほとんどです(特に日次や日中ロードによって3dが2dと極めて近い場合)。
ここから第1の単純化戦略が導かれます:2dのタイムラインは、第一段階としてサテライトの単なる「1属性」として格納します。 これにより情報の欠落を防ぎ、将来必要になった際に特殊な監査分析を行えるようにします。
第1の単純化戦略:2d(登録時刻)は通常のサテライト属性として格納する
これにより、3次元の立方体空間から、2次元の平面だけを考えればよくなります:
第3の次元(3d)は、データウェアハウスにデータがロードされた日時です。3d軸の最大の特徴は、「DWHチームの完全なコントロール下にある」という点です。DWH領域に長く携わる誰もが知る通り、私たちはソースシステムを決して盲信しません。
3d軸:新しい情報が過去の情報を暗黙的に置き換える(注:Petrが筆者の名前の正しい綴りです)。
議論の対象:誤りの訂正 vs 現実世界の履歴
DWHへのロードがソースシステムでの発生と極めて時間的に近いと仮定し、2dを単なるサテライト属性として一旦脇に置いたとします。では、私たちが「SCD Type 2」と呼んでいるものは、1d(業務有効期間)でしょうか、それとも3d(ロード日時)でしょうか?
これは業界によって認識が分かれます。例えば保険業界ではソース側で1d履歴を管理することが義務付けられているため、多くの保険ユーザーにとって1dが主たる時間軸です。一方、他業界では住所などの一部例外を除きソース側で1d履歴を持たないことが多いため、3dが主要な時間軸とみなされがちです。
理想的な世界において、3d軸の目的は「ある特定の時点でDWHが何を把握していたか」を示すことに尽きます。例えば、2月2日時点のデータに基づいて1月分の営業コミッションを算出した後、ソース側で契約キャンセルの修正が入ったとしても、数ヶ月後に当時の算出結果を完全に再現する場合などです。
問題は、本来ソース側で1d履歴として持つべきデータが、ソースシステムの機能不足により履歴管理されていないケースです。例えばECサイトで「1回目の注文時はチューリッヒ在住、2回目の注文時はバーゼル在住」という履歴が配送分析に不可欠であるにもかかわらず、顧客マスターが上書き更新しか対応していない場合、DWH側で3d軸を1d軸の最善の近似値(代理)として代用することになります。
「真の歴史」vs「ビジネスに関連する歴史」
たとえ現実世界における変化の歴史が存在したとしても、自社のビジネスモデルにおいて「過去の氏名が何であったか」がどうでもよい場合(マグカップに名前を印字して販売するようなビジネスでない限り)、なぜその履歴をレポートに載せる必要があるのでしょうか?
将来の要件変更に備えて3dタイムラインに完全な変更履歴を蓄積しておくことは不可欠ですが、「それをレポートに出力するかどうか」は完全に別の問題です。
新製品の案内メール配信リストを作成する際、関心があるのは「現時点で正しい顧客名と最新の住所」だけです。過去の住所や改姓前の旧姓は一切不要です。
したがって、多くのレポーティング要件においては、複雑な履歴期間を出力するのではなく、時点ビュー(as-now、as-then、as-of)に縮約して提示する方が、レポートの使い勝手を劇的に向上させ、集計ミスを防止できます(注2)。
DWHにおける1d履歴のモデリング(注3)
ソースから契約番号のような同一ビジネスキーに対して複数の有効エントリ(異なる有効期間)が届く場合、標準のサテライトでは同一ロード時に1つのタプルしか保持できません。
解決策は2つあります:
- マルチアクティブサテライト(MAS / Bi-Temporal Satellite)を使用する
- ハブの粒度を変更し、「テンポラル・インスタンス・ハブ(Temporal Instance Hub)」を作成する
第2の単純化戦略:ビジネスキーにビジネス有効開始日時(Valid From)を連結してテンポラル・インスタンス・ハブを作成する
マルチアクティブサテライトはハブを新設しないため一見スリムですが、モデル内でオブジェクトの特定のバージョンを直接参照(リレーション結合)できないという重大な欠点があります(注4)。
例えば保険契約において、2018年は補償額1億円、2019年は2億円に増額されたとします。2019年2月に事故報告があり、実際の事故発生日は2018年11月であった場合、マルチアクティブサテライトでは事故(Claim)をポリシー全体にしか紐付けられず、適切な補償額インスタンスの判定をビジネスルール側で複雑に記述しなければなりません。
一方、ポリシー・インスタンス・ハブを採用していれば、事故を該当期間のポリシーインスタンスに直接リンクできます。
さらに、過去の特定のタイムスライスのみに訂正が入った場合でも、テンポラル・インスタンス・ハブであれば標準のロードパターンで3dタイムラインを正常に更新できます。このため、Datavault Builderではテンポラル・インスタンス・ハブのアプローチを標準でサポートしています。
ディメンション属性のインスタンス化(Instantiation)
分析要件において、特定の属性の過去状態が極めて重要な場合があります。
例えば、ある顧客企業は製品を自社製造することもあれば、外部から仕入れて販売することもあります。品質保証の観点から、「受注時点でその製品が自社製だったか外注品だったか」を記録することが極めて重要ですが、商品マスターシステムには過去の履歴が保持されていません。
Kimballの古典的モデリングでは、受注明細を「ファクト」、製品特性をSCD Type 2の「ディメンション」として出力し、製品名などの非履歴属性はSCD Type 1として別出しします。その結果、レポート側では同一オブジェクトに対して2つの外部キーを結合しなければならず、クエリが著しく複雑化します。
Data Vaultモデリングには、これを極めてエレガントに解決する手法があります。トランザクション(受注明細)がRaw Vaultにロードされた時点で、製品属性に対する「as-of-now ルックアップ」を実行し、トランザクション側のBusiness Vaultサテライトにその属性をコピーして固定するのです。
これを筆者は**「別粒度への属性のインスタンス化(Instantiation of an attribute on another grain)」**と呼んでいます。
第3の単純化戦略:特定の時点における属性値をトランザクション粒度へとインスタンス化(固定保存)する
レポート層で受注明細を出力する際、受注時点の製品特性が既にトランザクション側に保持されているため、レポート出力時の複雑な時系列ルックアップが一切不要になります。
まとめ
以下の3大単純化戦略を活用することで:
- 2d(登録日時)はサテライト内の属性としてシンプルに保持する
- 1d(業務有効期間)をハブキーに含めてテンポラル・インスタンス・ハブ化する
- 時点依存の属性をトランザクション粒度へとインスタンス化する
ほとんどの業界における履歴出力要件の大半を、モデルの破綻やレポートの複雑化を招くことなくスマートに解決できます。
脚注
1 バーゼル在住の例は架空の話です。言うまでもなく筆者がバーゼルに住むことはあり得ません(バーゼル市民がチューリッヒに住みたがらないのと同様です)。
2 ソースシステムでの入力品質を監査するような特殊なレポートは除きます。
3 1dの近似として3d履歴を利用する場合も同様に適用可能です。
4 複数のマルチアクティブサテライトを結合する際にデカルト積が生じる問題は、バイテンポラルサテライトの特殊形態とメタデータ定義によって自動化パターンを構築可能です。