業務系におけるDB設計1

業務系だと、DB設計は大体ショボくて、その割に今までのアプリを動かさないといけないという下位互換性は異常なほど求められるので(大抵はマネージャが既存機能を見切る度胸がない)、既存仕様を削らずに拡張するので、こんなことが起こる。

 Table : User
   String name
   int gender_flag  ( 0:male, 1:female )

  ↓法人を追加したくなった

 Table : User
   String name
   int gender_flag  ( 0:male, 1:female, 2:corporate )

で、こんなコードを書いていてバグる。

 if ( gender_flag == 0 ){
    // for male
  } else { 
    // for female
  }

じゃ、どうするかというと、当然ながらソースコード

  if ( gender_flag == 0 ){
    // for male
  } else if ( gender_flag == 1 ){
    // for female
  } else {
    throw Exception
  }

にするわけですが、DB設計する時にも注意しないといけなくて、

  • いいから flag は 0/1 にしておけ。
  • 付け焼刃の設計は使い捨てだけにしておけ

ですね。
上の場合だと、対応方法としては、

  • 法人の用途に合わせて、Userテーブルに追加するべきか、別途法人用テーブルを作成するのか、などを検討する
  • boolean user_type ( 0:human, 1:corporate, default:0 ) を加える(可能であれば if user_type = 0, gender_flag should be set のような制約条件が欲しい)

とかでしょうか。


ちなみに、一般的には「クソ設計するなよ」というのが常識だとは思いますが、実は私は、付け焼刃設計してもいいときはあると思っていて、その条件はこんな感じ。

  • エンハンス余地があまりない、作りきりのアプリケーション(SIで基本的には使って、せいぜい5〜10年程度で技術進歩により新しいシステムが欲しくなったりして使わなくなる。とか、企画として作成して、当たったら広げようかな、みたいなのとか。)
  • 設計が複雑怪奇すぎて、手をつけること自体に非常にコストがかかる
  • もうからない
  • まともな設計ができる技術者がいない

要は、継続性を気にしない、もしくは下手に頑張ったら痛い目に遭う、といった場合は、敗戦処理にコストをかけない方がいいですよ、ということですね。