« 開発基盤のトリガーとDBMSのトリガー | トップページ | 逆方向バリデーションを自動化する »

2012.02.26

マスターテーブルと「有効期間」

 マスターテーブルには「比較的変化しないデータ」が登録されるが、M&Aが常態化した結果、取引先マスターあたりは頻繁に変わるようになった。社名や取引条件が変わるだけでなく、複数の取引先が1社に統合されることもある。

 ここらへんは、マスターデータに「有効期間」を設けるべきかどうかの問題としてしばしば話題になる。「有効期間を含むテーブルとの参照関係」の記事でも触れたが、もう少し補足しておきたい。結論を先に言えば「ケースバイケースではあるが、それほど神経質になる必要はない」ということだ。

 まず、有効期間を伴わない通常例を見よう。(1)では、すべての属性項目が主キーであるidに関数従属している。

(1)期間管理しないパターン

[得意先GRP] GRP_id、グループ名、...
+        012   Mグループ

└―…[得意先] 得意先id、社名、GRP_id、...
           00001  M社   012

 期間管理するために属性項目の一部を切り出した形が(2)である。子テーブルの主キーは、親の主キーである「得意先id」と「発効日」とが複合したものだ。ここでは「得意先GRP(グループ)id」を期間属性として切り出している。得意先がどのグループに所属するかもM&Aで頻繁に変化する情報のひとつで、月次で得意先GRP毎に販売実績を集計するようなシステム要件があれば、このようなモデルとなる。

(2)一部の属性を期間管理するパターン

[得意先] 得意先id、社名、...
+      00001   M社

└―∈[得意先期間属性] 得意先id、発効日、GRP_id
┌―…             00001 11/04/01  012
|                00001 12/04/01  256

[得意先GRP] GRP_id、グループ名、...
          012    Xグループ
          256    Yグループ

 期間属性を持たせたのであれば、その検索時に「基準日」が求められる点に注意してほしい。得意先の属性を知るための参照元上の手がかりとして「得意先id=00001」では不十分で、「基準日12/05/18における、得意先id=00001」といった手がかりで探索されなければ属性値は揃わない。参照元上の「基準日(受注テーブルであれば受注日あたりに相当する)」が既存レコードの発効日と一致するわけではない点にも注意されたい(つまり参照元テーブルとは「動的参照関係」を成す)。

 もっと徹底して、すべての属性を期間管理したいのであれば(3)のようになる。属性の一部でも変われば、新しい有効期間をともなうレコードを追加する形になっている。ちょっと大げさ過ぎる感じだが、あり得ないデータ要件ではない。

(3)すべての属性を期間管理するパターン

[得意先GRP] GRP_id、グループ名、...
+        012   Xグループ
|        256   Yグループ

└―…[得意先] 得意先id、発効日、社名、GRP_id、失効日、...
           00001 11/04/01 M社  012  12/01/01
           00001 12/01/01 P社  012  12/04/01
           00001 12/04/01 P社  256  99/12/31

 なお「期間管理しなくてよい属性」であっても、特定日に一括変更されるような事態が起こり得る。その際にはどのように対処すればよいのだろう。更新日の前夜に残業して更新する?その必要はない。たとえば、次のようなテーブルを用意すればよい。

(4)指定日に実行されるスクリプト

[自動実行JOB] JobID,実行日,実行順序,Script,...

 毎晩の日付変更時に自動実行されるようなプログラムを用意して、このテーブルを読ませるようにする。たとえば(1)や(2)のモデル上の"M社"の社名が半年後に"P社"に変わることがわかったなら、更新用のスクリプトをさっそく登録しておけばよい。半年後の指定実行日が到来すれば、社名が自動更新される。テーブル間の複雑な整合性が問題になるような項目向けには無理だが、そもそもそのような項目については期間管理することも難しい。

 なお、上の例で「得意先GRP別の集計処理」が必要だからといっても、必ずしも(2)の形にこだわる必要はない。(4)のようなしくみを用いて得意先GRPを自動更新しつつ、売上実績に得意先GRPを「スナップショット属性」として記録しておけば、(1)のままでよい。また、過去のすべてのデータ状況を当時のままに復元したいというのなら、月次あたりでマスターとトランザクション、さらにアプリもセットでバックアップしてしまえばよい。

 けっきょくのところ、「マスター項目を期間管理すべきかどうかはケースバイケース」としか言えない。必要ならそうすべきだし、必要ないならそうすべきではない。ようするに、データ要件を洞察して、要件どおりのDB構造を設計すればよい。もちろんそれは簡単な仕事ではないが、開発者に期待される専門性のひとつではある。

本ブログでの関連記事:
「有効期間」を含むテーブルとの参照関係

|

« 開発基盤のトリガーとDBMSのトリガー | トップページ | 逆方向バリデーションを自動化する »

コメント

コメントを書く



(ウェブ上には掲載しません)




トラックバック


この記事へのトラックバック一覧です: マスターテーブルと「有効期間」:

« 開発基盤のトリガーとDBMSのトリガー | トップページ | 逆方向バリデーションを自動化する »