ID Required
どのテーブルにも「id」という名前の主キーが必要という考えに起因したアンチパターン。
そもそも主キーって?
データ行を一意であると識別するためのキー。
「PRIMARY KEY」とも呼ばれている。
主キーにはNULLは許容されておらず、格納されるデータが一意である必要がある。
主キーにはどのカラムを選択しても理論上は問題ないが一意であることが条件であるため「名前」や「メールアドレス」のような重複する可能性のあるカラムを主キーに設定するべきではない。
ID Requiredの何がいけないのか?
以下のような中間テーブルがあったとする。
このテーブルでは書籍を管理するための「book_id」とその書籍の解説を管理するための「description_id」が格納されている。
パターン1
このテーブルでは1つの書籍に対して1つの解説として組み合わせが一意となるようにデータを格納したい。
物理名 | 主キー |
---|---|
id | ◯ |
book_id | |
description_id |
上記の構成だと以下のように主キーの重複はないが「book_id」と「description_id」の組み合わせが重複するデータが入ってしまう可能性がある。
id | book_id | description_id |
---|---|---|
1 | 1 | 1 |
2 | 2 | 2 |
3 | 2 | 2 |
パターン2
パターン1の重複を踏まえて以下のように「book_id」と「description_id」に「UNIQUE KEY」を設定すれば組み合わせの重複を防ぐことができた。
物理名 | 主キー | ユニークキー |
---|---|---|
id | ◯ | |
book_id | ◯ | |
description_id | ◯ |
ん.....?
パターン2では「book_id」と「description_id」にユニークキーを設定することで重複を防ぐことができた。
なら「id」ってなんのためにあるの.....?
パターン3
このパターンでは「description」が同テーブルに格納されています。
このテーブルでも同様に、書籍の重複がないように「UNIQUE KEY」を設定しています。
物理名 | 主キー | ユニークキー |
---|---|---|
id | ◯ | |
book_id | ◯ | |
description |
このパターンでは「book_id」に「UNIQUE KEY」が設定されており自然キーとして使用できる。
そのため、「book_id」を主キーに設定すれば「id」列はやはり不要となる。
ではどうしたら良いのか
前提として主キー、及びユニークなフィールドがないとレコードの特定ができず重複したデータを複数格納してしまうことがあります。
そもそも主キーって?の項目でも記載しましたが格納されるデータが一意である必要があり、主キーを設定することでテーブル内の全ての行が一意であることを保証してくれる。
また外部キーからの参照によりテーブルとテーブルの関連付けを行うため重要である。
再びそもそも主キーって?の項目した内容ではあるが、主キーにはどのカラムを選択しても理論上は問題ないが一意であることが条件であるため「名前」や「メールアドレス」のような重複する可能性のあるカラムを主キーに設定するべきではない。
それを踏まえてどうしたら良いのか
パターン2のような場合ではid列が使用されずに無駄な列になってしまうため複合主キーを使用する方法などがあります。
中間テーブルなどの場合は組み合わせによって一意であることが担保されるため無駄な列ができない。
パターン3の場合は主キー列以外にユニークなキーがあり自然キーとして使用できるため、その場合は自然キーを主キーとして設定することで無駄な列を排除することもできる。
まとめ
アンチパターンとならないために。
自然キーや複合キーを活用することで一意であることも保証した上で冗長なキーの作成を減らすことができる。
フレームワークなどによっては「id」列を持つことで利用できる機能等もあるため、一概にアンチパターンを排除すべきではない場合もある。
次回
Keyless Entry