結論
以上に述べてきましたように、マスタデータの変更履歴を蓄積する必要がある場合は、正規型スキーマを採用する、ただし結合型の属性はトランザクションデータに埋め込む、というのが私の結論です。
では、具体的にどのように蓄積するかといいますと、これには2つの方法があります。一つは変更差分を蓄積してゆく方法、もう一つはバージョンを持つ方法です。業務系システムから変更差分を抽出できるならば前者がよいと思います。なぜなら、バージョンを持つ方法は日次や月次でマスタデータ全体を積んで行くことになるので、蓄積するデータ量が膨大になりディスクを大量に消費してしまうこと、さらにバージョン間の履歴が欠落する可能性があるためです。
もし、変更差分を蓄積する場合は、マスタデータに次の属性(すべてまたは一部)を追加することで、ある一時点の状況を切り出せるようになるでしょう。
- 有効期間(開始、終了):レコードの有効期間
- 削除フラグ:業務系システムで削除されたことを示す
- 更新日時:最後に属性が更新された日時
- 最新フラグ:同一マスタコードの複数レコードの中で最新のデータを示す
最後に、時系列データのクエリに関して少々お話したいと思います。
すでにお気づきのことと思いますが、時系列データをクエリする場合は、常に「いつの時点でデータを見るのか」という考慮が必要になります。まず、ユーザがデータを見る時点(現時点かもしれないし、昨年度末の時点かもしれません)のマスタデータの状況を切り出して、それをトランザクションデータに適用するという2ステップが必要だということです。第1ステップの切り出し作業は、上記のカラムが用意されていれば可能です。さらに、一番参照頻度が高いと思われる最新時点の状況は、最新フラグを使用して作成したビューを提供します。このビューの提供により、OLAPツールで直接検索することも可能になりますし、またデータマートを作成する場合のデータ抽出も容易になります。
「恒常的」という特性について
「恒常的」に関する疑問は、業務系システムにおいてマスタデータ(マスタコード以外の属性)が変更された場合、あるいはマスタコード自体が変更された場合に、データウェアハウスではどのように対応するのかということでした。
まず、マスタデータについてですが、なぜこの問題が発生するのかと言うと、分離型の属性がトランザクションデータに埋め込まれているからです。結合型の属性と違い、分離型の属性はトランザクション発生時点の値が重要なのではありません。だからこそ、業務系システムでは値が変更されたとき、一括して更新するのです。したがって、この問題の対応方法としては、分離型の属性を埋め込まない(Transformする際に削ぎ落とす)か、あるいは業務系システムと同じ対応をすることだと私は考えています。
次に、マスタコードの変更にどう対応するかということですが、これには次の3通りの対応方法があると思います。
- マスタデータの変更差分は追加せず、データウェアハウス内のすべての該当コードを更新する。
- データウェアハウス専用のコードを設け、複数の異なるマスタコードを同一実体に紐付ける。
- 根本となる業務系システムに不変なコード体系を導入する。
この中で一番実現性が低いのは③だと思いますが、私は個人的にはこの方法が最も正しいと考えています。マスタコードというのは実体を識別するものであり、実世界において実体は不変です。したがってデータベース内においてマスタコードは不変であるべきで、人がマスタコードに意味を持たせるから変化してデータベース内で不都合が発生します。変化して当たり前ならば、それは実体を識別するものではなく、単なる属性として管理すればよく、そうすればこの問題は発生しないと考えています。
(次回へ続く)