T字系ER手法で僕がしていた論理削除(via とりあえず削除フラグ)

@t_wadaさんのこのスライド

www.slideshare.net

 

パラパラと眺めていたら「T字系ER手法」ってのが出てきて、久しぶりにいろいろ思い出してしまったので、ちょっと書こうかなと思います。

 

T字系ER手法は西暦2000年あたりにSIerの一部で流行っていたデータベース設計手法で、原則(なのか?)についてはこのエントリーに書いてもらってあるとおりです。

mike-neck.hatenadiary.com

 

抜き出すと、

  • テーブルに状態を持たせない
  • 究極には機械が認識するキーと、人間にとって意味のあるデータだけのエンティティだけですべての業務のデータを構成できる
  • 日付を持つデータはイベント(これもひとつのエンティティ)
  • NULLのデータは絶対に持ってはならない
  • テーブルはでかく作るな、小さく作れ
  • テーブル同士の関連は直接持つな、関連を表すテーブルを作れ
  • 1:1の関連になったとしても、イベントとそれに付随するデータは分離しろ
  • データが増える?金と物理で殴れ(ディスク増強しろ)

1システム1600テーブルあるとか言うのもあながち嘘ではなく、テーブルを分割してナンボみたいなおかしな雰囲気が漂っていたことを思い出しました。

ま、ここまでテーブルが増えると、発行するSQLはJOINの嵐で、酷いものではA41枚にビッシリSELECT文が1個だけだったりして、どうやってテストしてたのか思い出したくもありません。(テストしてません)

当然のことながら、その後のO/Rマッピングの勢力拡大によって、この設計手法は衰退の一途を辿ることになります。プログラマ泣かせでしたし、ほんとよかった。

 

T字系ER手法の原則にある「テーブルに状態を持たせない」というのは、「ステータス列を持たせない」ということです。ステータスを持つようなテーブルをどのように設計していたかというと、とにかくテーブルを分割してました。

例えば、社員でいうと、

  • 社員
  • 退職者

という2つのテーブルを実装します。(これを社員のサブセットと呼んでました。)

この2つのテーブル、含まれる列の構成はほぼ同じで、退職日列が含まれるか含まれないか程度の違いです。「テーブルに状態を持たせない」というよりも、テーブル自体が状態を表していると言えます。

 

ちなみに、先のエントリーでも、こういった社員テーブルはマスター(リソース)でないとおっしゃっていますが、入社、退職というイベントが起きるのでイベントとして扱うようにと、僕も言われていました。(ER手法という名前は、たしか、イベントとリソースの頭文字を取ったんじゃないかなと思います。)

 

で、本題の論理削除ですが、このケースだと、

  • 社員テーブルのデータを退職者テーブルに移動(&退職日を入れる)

としていました。つまり、退職者テーブルにINSERTして、社員テーブルからDELETE。

削除フラグを立てるという論理削除ではなく、いわゆる履歴テーブルみたいな使い方をしていたなあと思い出しました。トランザクショナルな永続的なデータストアといえばそうです。

 

まあ、この設計方法は、論理削除を論じる前に、テーブル構成が冗長になることでの混乱が大きいと思います。マイグレートしながら実装を進めるようなイマ風の開発には向きません。

いま僕が設計するなら、社員と退職者のテーブルはまとめて退職日列を持ちます。削除フラグは持ちませんが、状態を表すような日付列を持つと思います。