※わりと初心者向けの記事になることをご了承ください。上級者からは総突っ込みを受けそうなのでハードルを下げておきます。
ER図とは
ER図(ER diagram)はDBのつながりを図(ダイアグラム)で表現したもので、
各テーブルの外部キー、インデックスなどの関連性を示すのにもっともポピュラーな方法(だと私は考えている)。
~ここからすこし雑談~
例は以下に示していくつもりだが、複雑なDB構造を目の当たりにし、設計書もない場合、
「デバッグしながら」
「画面操作しながら」
「保存ボタンを押したらどのテーブルに何が入るのか見ていく」
みたいな不毛なことをやってテーブル構造を把握せざるを得ない。
本来ならテーブルの更新(create、alterなど)と同時にER図もメンテするフローになっていたら
「XXサブのYYってどのテーブルに入るのでしょうか?」
「AAAテーブルのbbbカラムってどのテーブルとつながっているのですか?」
のような無駄なコミュニケーションがなくなると考えている。
ただうちの会社では、機能開発においてER図が必須ではないので、
新人をチームに迎えるたびにこのようなコミュニケーションは頻発する。
たしかにメンテはめんどくさいが、いろいろ出来るみたいなので、
開発フローが未熟だったり固まっていないスタートアップ企業や個人で開発をするときは取り入れてみるのもいいかもしれない。
ちなみに私は個人で開発しているWebアプリでもER図を書くことがある(複雑になる場合)。
ERMaster
何のツールがBestか分からないが、
うちの会社ではeclipseが最もポピュラーなIDEなので、
eclipseプラグインがあって最強らしいERMasterを使っていこうと思う。
ERMasterのプラグインをインストールする
- eclipseは3.3以上を使ってください(最新はこちら)
- eclipseを開いて、Help > Install New Software... と選択
- Available Software というダイアログが開くのでAddボタンを押下
- Nameに「ERMaster」、Locationには「**http://ermaster.sourceforge.net/update-site/**」をコピペ
- Addボタンで追加できる
- Work Withの選択肢の中に登録したERMasterが出てくるので選択
- 下の枠にERMasterが出てくるのでチェックボックスにチェックをしてNext
- とにかくNext(チェックつけなおすとかは不要)
- 同意チェックしてFinish
- 警告が出るがinstall Anywayでインストール続行
- 画面の通りに設定していけばインストールができ、eclipse再起動を促してくるので従う
- 再起動すれば、「File > New > other」のなかにERMasterが出てくるのでこれで準備は完了。
テーブル構造をER図にしていく
絶望しかけたテーブル構造を整理していく。
※ただし社外秘情報を含んでしまうためテーブルはサンプルのものを利用する。競馬好きなので競馬を例にする。
DBは以下の3つ
競走馬情報
CREATE TABLE IF NOT EXISTS horse_info (
horse_id varchar(80) not null,
horse_name varchar(80)
);
馬ごとのレースの結果
CREATE TABLE IF NOT EXISTS race_result (
horse_id varchar(80) not null ,
race_id varchar(80) not null ,
result varchar(80)
);
レース情報
CREATE TABLE IF NOT EXISTS race_info_data (
race_id varchar(80) not null ,
race_date varchar(80),
race_name varchar(80)
);
-
作成したいプロジェクトを選択しておく(まっさらのところには作れないっぽい)
-
Nextでファイル名を決める(race_rsult_structureとする)
-
databaseを選択(私はプライベートではPostgreSQLユーザーなのでPostgreSQLをえらぶ)
あとはここに上記の3個のテーブルを記述してつないでいく。
ここからつないでいくのですが、新規にテーブルを作るときはこれをやってはだめです。
今回の目的はアンチパターン防止です。
今回の3テーブルは馬の情報、レースの情報をマスタ情報として保持し、
それぞれのテーブルを結果のテーブルでつなぐことで以下のような最悪の構造を防ぐということをやりたいのです。
競走馬のレース結果情報
CREATE TABLE IF NOT EXISTS horse_race_result (
horse_name varchar(80),
race_date varchar(80),
race_course varchar(80),
race_name varchar(80),
result varchar(80)
);
こうなると最悪なのは、レースの名前や馬の名前、情報をメンテしようとしたら
複数の行をメンテしなければならず、保守性が低くなります。
ディープインパクトは1頭しかいないし、2020年の有馬記念は1回しかありません。
なので、それぞれマスタで保持して唯一無二の状態にし、それぞれにIDを振って
外部キーで結合したresultだけを持つテーブルを作成すればよいということになります。
なので、まず2つのテーブル + resultだけを持ったテーブルにします。
ここに1:N関連を使ってHORSE_INFO→RACE_RESULT、RACE_INFO→RACE_RESULTという方向につないでいくと、
以下のようになります。
※1:N関連をHORSE_INFO→RACE_RESULT、RACE_INFO→RACE_RESULTという方向に使うのは、
上述した通り、ディープインパクトは1頭しかいないし、2020年の有馬記念は1回しかないので、1。
でもディープインパクトは有馬記念だけでなく天皇賞にも出てるし、凱旋門賞にも出ている。
つまり結果は複数存在するのでN。
この考え方はDB構造、テーブル構造を検討するときに重要なので持っておくべきです。
このように最初から何をキーにしなければならないのかを検討する以前に
- マスタ情報は何か
- 唯一無二のもの、複数あり得るものは何か
を検討し、ER図を作っていくと、間違っても前出のアンチパターンのようなDBを作ることはなくなるわけです。
最後に
実際の製品のテーブルのER図で絶望しています。皆さんきれいで保守しやすいDBを作りましょう。
そして機能追加、新プロダクト、新サブシステムを実装する場合はぜひER図を用いて考えてみてください。