SQLアンチパターン-10章 31のフレーバー-まとめ


列に入る値を限定する

列に入る値を限定するとき、テーブル設計時にCHECK制約を利用することで定義が可能になります。

また、MySQLではENUMというデータ型をサポートしています。

CREATE TABLE Books (
 author VARCHAR(100)
 category ENUM('human','social','history')
);

しかし、上記のようにテーブルを設計したとして、
category列でソートをかけるとどうなるでしょうか。
答えは、アルファベット順にソートされるのではなく
値のリストの定義順でソートされることになります。

デメリット

ENUMCHECK制約を使う際には、その中の値が今後変更されうることが起きないか、新しい値が追加される可能性があるのか、よく考えましょう。

列定義を変更する

列定義をもし追加するとしたら、元々の列定義の内容を知っておく必要があります。
また、定義されている値を変更する場合は既存のデータを編集した上で更新する必要が出てきます。
それはとてもコストのかかる作業となります。

データの移植が難しい

例えばENUM型はMySQLでしか対応しておらず、他のDBに移植しようとなった場合には設計を見直す必要があります。

解決策

限定する値は別テーブルで定義しましょう

今回の場合、外部キーでcategoryテーブルを扱えば問題は簡単になるでしょう。
categoryの値を変更することもできるし、
新しくcateogryを増やすことも容易になります。
データの属性が増えた場合も変更は容易です。
例えばcategoryを扱う際に、親子関係を考える必要が出てきたとします。
その際はcategoryテーブルでその親子関係を表せば良いです。(Closure tableなどを使いましょう)
ENUMCHECK制約で設計していては実現できないことです。

値の制限を、テーブルを増やして表しただけなので
他のDBへの移植も容易です。