こんにちは、土屋です。
今回の記事では、私が初めてテーブル設計をしたときに、つまずいた話をまとめてみました。
テーブル設計の経験者の方には、「新人はこんなところでミスするんだ」と知っていただければいいなと思います。
【ミスその1】エンティティの属性の書き方が適切ではなかった
論理名を簡潔に書く
社員情報をまとめるエンティティに、社員のIDを属性として入れたいときがありました。
はじめは属性の論理名を、次のように「社員ID」にしていました。
ですが、「社員ID」ではなく、簡潔に「ID」とだけ書けばOKです(※)。
エンティティ「社員」の属性にIDがあると、それが「社員ID」であるのは自明だからです。
※必ずしも当てはまるわけではありません。例えば、全てのテーブルで「社員ID」にしておくと、JOIN するときに迷いにくいので便利という意見もあります。
正しい表現か確認しながら物理名を書く
物理名を考えるときに、はじめは「日本語の論理名をGoogle翻訳で英語にしたらいいんでしょ?余裕~」と思っていました。
ですが、実際は翻訳だけではなく、物理名が本当に正しい表現か吟味しなければならず、予想以上に大変でした。
私が考えた論理名をもとに翻訳した英語をそのまま物理名として使うと、他の人にとっては意味が分かりづらいことが多くあったからです。
例を挙げると、「案件」の論理名を翻訳して出てきた"case"を、そのまま物理名にしたときがありました。
ですが、他の人は"case"という単語を見ても「案件」という意味には結びつきませんでした。
私が所属しているグループでは、「案件」= "project"という意味で日常的に使用していたからです。
そのため、「案件」の物理名には"project"を採用しました(※)。
※そもそも"case" は予約語なので、物理名として使うのは基本的に避けた方が良いです。予約語は2重引用符で囲まないとカラム名などに使用できず、扱いづらいからです。
翻訳した後に本当に正しい表現なのか考え直し、いくら物理名を考えてもしっくりこないときは、日本語の論理名から見直すようにしました。
物理名の付け方はまだ難しいと感じていますが、少なくとも、Google翻訳に頼ってつけたり、パッとみて適当につけたりするのではなく、本当に正しい表現か確認しながら名前をつけるようにしています。
【ミスその2】要件に沿ったデータ型を考慮していなかった
テーブル設計で、あるイベントに対して、対応するべきかどうかを管理したいと思うときがありました。
経験者ならデータ型にboolean型を使うところだと思いますが、私は対応するべきならint型で"1"、対応しなくてもいいなら"0"もしくは"NULL"がはいるように設計しました。
最初にint型で値を持つ方法を思いついたので、何となくそのままint型にしていたのです。
するとアプリケーションのコードを書くときに、単純にint型で扱おうとしてしまい、システムの要件と合わない場面が出てきてしまいました。
この失敗から、次の3つのポイントを学びました。
- boolean型ではなくわざわざint型が使われていると、読み手は何か意味があると思ってしまう
- 想定外の値が入る可能性がある
- コードを書く時点でデータ型を修正しようとすると、修正にかかるコストが大きい
要件に合わせた適切なデータ型をあてなければいけなかったなあと反省しました。
【ミスその3】適切にNOT NULL制約をつけていなかった
エンティティのある属性を、必須項目として管理する必要があったときに、属性にNOT NULL制約をつけませんでした。
NOT NULL制約をつけなかった理由は、いつかNULLを許容するときがあるかもしれないと、なんとなく考えていたからです。
そしてNOT NULL制約をつけていないことを忘れ、コードを書く段階でも、データがNULLにならないような制御をかけていませんでした。
その結果、アプリケーションをつくってテストをしたときに、必須項目のデータに値を入力しなくても、データベースに登録できてしまう事態が起きてしまいました。
システムの要件として、NULLを許容しない属性だったので、NOT NULL制約をつけるべきだったと反省しました(※)。
※NOT NULL制約の有無は、十分に検討する必要があります。
制約がないことによってデータの整合性がとれない場合もありますが、まれに、一時的に制約が崩れるような操作が必要なときに、制約によって困る場合もあるそうです。
私はまだ1人で判断することができないので、先輩社員に相談しながら制約をあてるようにしています。
【ミスその4】中間テーブルのリレーションを間違えた
例えば次のような「多」対「多」のエンティティがあったとします。
エンティティ間の関係を「1」対「多」にしようとして、中間テーブルを立てようと思いました。
このとき、学生や講義のエンティティに対して、中間テーブルが「1」か「多」なのか分からなくなりました。
はじめは「多対多の間にテーブルをつくるから中間テーブルは1じゃないのか?」と思い、次の図のようなリレーションを考えていました。
実際は次の図のようになります。
リレーションについて考えるときは、2つのエンティティの関係に注目することで解決しました。
1人の学生が受講する講義は複数あるので、エンティティ「学生」が「1」に対して、エンティティ「受講」が「多」になります。
一方で1つの講義に対して複数の学生が受講するので、エンティティ「講義」が「1」に対して、エンティティ「受講」が「多」になります。
【ミスその5】ER図のリレーションが分かりづらかった
初めてER図を書くときに、次の図のように、中心にエンティティを1つおき、何となくマインドマップを書くように他のエンティティを展開させていました。
読むことはできますが、エンティティ間のリレーションが分かりづらいので、配置を修正しました。
次の図のように、1か所(図だと左上のエンティティ)から放射線状に展開するように修正しました。
分かりやすい図にすることができました。
最後に
テーブル設計について勉強していると、書籍にも載っていないぐらい、ささいなことでつまずくことが多くありました。
まだまだテーブル設計について知らないことが多いので、これからもハマりながら学んでいこうと思います。
最後まで読んでいただき、ありがとうございました。