サーティワンフレーバー

IN句をつかったCHECK制約だけで列の値を制限するやり方には問題がありますよ。という指摘。プログラムで言うところの列挙型(ENUM)のようなもの。MySQLでも同様の機能があるようだ。
問題点は以下のとおり。

  • 許可されている値の一覧がわからない。CHECK制約から取ってくるのは大変。MySQLENUMでも同様の感じ。
  • 変更するのが結構大変なことがある。そもそもテーブル定義の変更はあまり行うべきではない。
  • 値の一つを変更するのが大変
  • RDBMS製品により機能などが違うので、移植が大変

アンチパターンを使っていいのは、値セットが変わらない限りはつかってもよい。とくに相互排他的な2つの値には良い。流動的な場合はテーブルを分けるべきとのこと。
特に異論はないのだが、こういうコードと名前しかないようなテーブルが増えるのが嫌なので、コードと名称をセットにした「いろんなコードマスタ」とでもよぶべきテーブルが作られているのをよく見る。

コードの分類 コード 名称 並び順 属性1 属性2
BugStatus NEW 新規 1 Blue Normal
BugStatus IN PROGRESS 対応中 2 Red Bold
BugStatus FIXED 完了 3 Green Normal
PersonalContacts Mr. Mr. 1 Male  

といったようなものだ。コードの分類はいわば属性名であり、コードはDBの格納値であり、名称はUIに出す名称、属性1と属性2はコードの分類ごとに自由に割り当てても良い属性である。ここでは色とフォントについての指定を記述している。
これをどう評価すべきだろう。おそらく本書の著者は否定するだろう。アンチパターンのいくつかがここに混じっている。
このアンチパターンで指摘されている問題は上記の設計は回避している。しかし、大きな問題はこの設計をしてもこれを使っているテーブルに対して制約がかかっていないということである。これをどう評価するかという点が、この設計を使うかどうかの分かれ目になるだろう。