« 業務システムとWEBサービス | トップページ | SI企業が「モデルシステム」を公開しない理由 »

2011.11.12

在庫DBにおける「正規化崩しの報い」

 DBに含まれるテーブルを「マスターとトランザクション」、あるいは「リソースとイベント」に分ける管理方針は広く取り入れられている。加えて、それらの中間的な区分として「残高」を想定することで、モデルをより効果的に理解できるようになる。

 ただし、「マスターかトランザクションか」や「リソースかイベントか」の区別も、「残高」の区別も、テーブル固有の属性ではない。あくまでも、「他のテーブルとの相対的な関係」において認識される「役割」のような概念である。

 つまり、あるテーブルがたまたまイベントテーブルとみなされているとしても、別の文脈ではリソース的、あるいは在庫的なものとして扱われることもある。ある場面で「父親」である人物が、別の場面では「息子」になったり「叔父」になったりするのと同じ話だ。それをふまえたうえでの議論として理解してほしい。

 さて、「残高テーブル」の大きな特徴は、多くの場合「正規化崩し」の事例となる点だ。何度か説明したように、正規化崩しには相応の「報い(むくい)」がともなう。すなわち、更新時異状に対処するためのこまごました配慮が必要になる。残高テーブルの設計における「正規化崩しの報い」の例を眺める前に、まずは「正規化崩し」を伴わない単純な残高テーブルのモデルを見よう。

例1

[商品] {商品ID},商品名,現在庫数

 これでもかまわないといえばかまわないのだが、在庫というのは重要な会計情報なので、その変化をトレースできる監査データが欲しい。そこで例2のように「受払(入出庫履歴)」が導入される。私があるテーブルを「残高」とみなすのは、まさにこのような取引履歴テーブルとの関係においてである。

例2

[商品] {商品ID},商品名,(入庫数)*1,(出庫数)*2,(現在庫数)*3


└─…[受払] {受払№},伝票区分,商品ID,取引日時,取引区分,取引数

  *1.入庫数=「受払」上の入庫分取引数の合計値
  *2.出庫数=「受払」上の出庫分取引数の合計値
  *3.現在庫数=入庫数-出庫数

 識別子の対応条件からこの関係を「参照関係」といい、「参照先」である商品レコード1件に、「参照元」の受払レコードが複数件対応する。ここでは示していないが、入出荷や棚卸や振替等を管理する多様なトランザクションテーブルが別途あって、そのデータを処理することで受払データは追加される。

 なお、モデル上で"(入庫数)"のようにカッコ書きされているフィールドは、それが「導出フィールド」であることを示す。つまりそれらは、商品テーブル上に実フィールドとしては置かれない。それぞれの注釈は値の導出手順で、なんらかのプログラムがそれらを計算して示してくれるので、わざわざテーブル上に物理的に置く必要がないのである。

 一見すると例2でうまくいきそうだが、問題がある。会社が起業されてから現在までの受払データをすべて持つのであればこれでいいが、現実にはそんなわけにはいかない。一定期間より過去の受払データはもともと存在していなかったり、消去されたりしている。それを前提にすれば、在庫DBは例3のようにモデリングされる。

例3

[商品] {商品ID},商品名,期首在庫数,
+          (当期入庫数)*1,(当期出庫数)*2,(現在庫数)*3


└─…[受払] {受払№},伝票区分,商品ID,取引日時,取引区分,取引数

  *1.当期入庫数=「受払」上の当期入庫分取引数の合計値
  *2.当期出庫数=「受払」上の当期出庫分取引数の合計値
  *3.現在庫数=期首在庫数+当期入庫数-当期出庫数

 あらたに追加された「期首在庫数」に注目してほしい。これは、前期末から「繰越」された数量のことだ。これに当期間の入出庫数を加減することで、「現在庫数」が導出されることになる。

 モデルとしては端的にまとまっているが、じつはこの形で実装されることもほとんどない。多くの場合、「当期入庫数」と「当期出庫数」が導出フィールドではなく実フィールドとして置かれる。本来ならばそれらは受払データから導出できるものなのだが、受払データが追加されるたびに受払取引数にもとづいて更新されるべきフィールドとして置かれる。

 これは「正規化崩し」に他ならない。なぜこのような調整がされるかというと、読取のレスポンスを良くするためだ。実際の在庫モデルはここに示したものよりもずっと複雑で、場所別、ロット別といった多彩な切り口をともなった形で設計される。そうなると、いちいち受払を集計して値を示すというやり方ではレスポンスが悪すぎる。

 しかし、正規化崩しには「報い」がともなう。報いを受けなければ、更新時異状によって「使えば使うほど壊れてゆくDB」が出来上がるからだ。最悪なのは、正規化しているかしていないかを把握しないままに漫然と設計を進めるやり方だ。それだと、設計者が気づかぬまま「使うほど壊れてゆくDB」になってしまっている可能性が高い。

 つまり、正規化崩しそのものは悪いことではなく、正規化を崩すことに関して「意図的でない」ことが悪いことである。なによりも「正規化崩しの報い」を確実に履行するためにこそ、正規化に関する知識は必要とされる。正規形がわかっていなければ、それを意図的に崩すこともできないからだ。

 では上述した正規化崩しの場合、システムはいかなる「報い」を受けるのか。受払データの集計値と当期入出庫数の集計値とが一致しているかどうかを検査するための管理ツール――そういうものをわざわざ開発する羽目になる。何かの理由で集計値の整合性が崩れたとき手早く対処するために、このようなツールは欠かせない。

 「自分は正規化などしない。あんなのマジメにやってたら、テーブルがやけに増えるし、処理が遅くてかなわない」と言う人たちの多くは、「正規化」だけでなく「正規化崩しの報い」までも無視してしまう。その結果、本来ならば開発者が受けるべき報いが「崇り(たたり)」となってユーザ企業を襲う。DB設計というのは、かくのごとく「因果応報」な営みなのである。

<過去の関連記事>
残高テーブルの設計と統計処理

|

« 業務システムとWEBサービス | トップページ | SI企業が「モデルシステム」を公開しない理由 »

コメント

コメントを書く



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




トラックバック


この記事へのトラックバック一覧です: 在庫DBにおける「正規化崩しの報い」:

« 業務システムとWEBサービス | トップページ | SI企業が「モデルシステム」を公開しない理由 »