どうも。つじけ(tsujikenzo)です。このシリーズでは「dbdiagram.ioでテキストからER図を書こう」について、全4回でご紹介します。今日は最終回です。
前回のおさらい
前回は、「DBML」をお送りしました。
今回は、「リレーションシップとカーディナリティ」をお送りします。
今日のアジェンダ
- リレーションシップと外部キー
- カーディナリティ
- 多対多の解消
リレーションシップと外部キー
テーブル同士を、外部キーで連結することを、リレーションシップと呼びます。
このように、片方のテーブルのカラム[country_code]と、もう片方のテーブルのカラム[code]を、リレーションさせることで、重複するデータがない設計ができます。
リレーションシップはこのように定義します。
コードを書いてみましょう。
//テーブル定義
Table members {
id int [pk, note:'less than 10']
full_name varchar [not null]
gender varchar(1) [default: 'm']
created_at timestamp
contry_code int [ref: > countries.code]
}
Table countries{
code int [pk]
name varchar [unique]
note:'Members origin'
}
キャンバスに、リレーションシップが反映されました。
リレーションシップの省略記法
リレーションシップには省略記法があります。これらは、テーブルの外で定義できます。
先ほどのコードを書き換えてみましょう。
//テーブル定義
Table members {
id int [pk, note:'less than 10']
full_name varchar [not null]
gender varchar(1) [default: 'm']
created_at timestamp
contry_code int //[ref: > countries.code]
}
Table countries{
code int [pk]
name varchar [unique]
note:'Members origin'
}
Ref: members.contry_code > countries.code
カーディナリティ
カーディナリティは3種類あります。それぞれ異なる記号を使って記述します。
1対1
社用メールを管理する、userとemailの2つのテーブルがあったばあい、リレーションシップは1対1になります。
しかし、1対1のリレーションシップは、1つのテーブルにまとめられるので、あまり見かけることはないでしょう。
日本語中国語訳対応表などを作成するばあいは、テーブルをわけるかもしれません。
1対多
注文書のような、見出し情報と明細情報がふくまれる帳票のリレーションシップは、1対多になります。
よくあるパターンなので、おぼえておきましょう。
多対多
実世界からエンティティを見つけて、リレーションシップを考えてみたところ、多対多(n対n) になることは、とてもよくあります。
リレーションがよくわからないときは、2つのテーブルを並べて、具体的な組み合わせを書き出しましょう。必ず1対多なのか、多対多なのかが見えてきます。
多対多の解消
多対多は、そのままでは、リレーショナルデータベースの設計に進むことができません。
多対多を解消するテクニックがあるので、ご紹介します。
中間テーブルを作成する
まず、中間テーブルを1つ作成します。テーブルの具体的なレコードも置きます。
中間テーブルで、作成されるレコードを、具体的に書き出してみます。
それぞれのリレーションシップを確認します。各レコードから何本のリレーションシップが出ているかを見ると、1対多か多対1になっていることがわかります。
テーブル[Users]と[Status]には、[UserStatus]というテーブルが必要だったことが浮かびあがりました。
リレーションシップは2つのテーブルとは限りません。このように複数のテーブルがリレーションしていることもあります。
最後に、複数のテーブルがリレーションしたテーブルを、コードで書いてみましょう。
Table users as U{
user_id int [pk]
name varchar
}
Table tasks as T{
task_id int [pk]
task varchar
}
Table status as S{
status_id int [pk]
status varchar
}
Table UserTaskStatus as UTS{
UserTaskStatus_id int [pk]
user_id int
task_id int
status_id int
created_at datetime
}
Ref:UTS.user_id < U.user_id
Ref:UTS.task_id < T.task_id
Ref:UTS.status_id < S.status_id
このようなER図を作成できました。
まとめ
以上で、「リレーションシップとカーディナリティ」をお送りしました。
DBMLには、他にもインデックスや、列挙型など、便利な構文があります。
DBML中級編として、いつかお届けできればいいなと思います。