エンティティ間の対応関係の多重度(1対1・1対多・多対多)。
カーディナリティ(多重度)とは、2つのエンティティ(=管理したいもの・人・出来事)が「何件対何件」で対応するかを表したものです。対応のパターンには「1対1」「1対多」「多対多」の3種類があります。
身近な例で考えると、親と子の関係に似ています。1人の親に子が複数いることもあれば(1対多)、夫婦のように1対1のものもあります。エンティティ同士も「いくつとつながるか」がそれぞれ決まっていて、それを数で書き表すのがカーディナリティです。
上のツールで▶ボタンを押すと、社員と社員証(1対1)、顧客と注文(1対多)、学生と科目(多対多)の3パターンを、実際のインスタンス同士を結ぶ線の本数で見比べられます。
多重度はE-R図の関連線の両端に書き込みます。書き方には流儀がありますが、よく使われるのは次の2つです。
・「1」「多」「N」「M」で書く方法:線の端に数や文字を直接書く。1対多なら片端に「1」、もう片端に「多(N)」と記す
・IE記法(鳥の足記法):「多」側の線の先を、鳥の足のように3本に枝分かれさせて表す。実務のER設計ツールで広く使われる
さらに細かく、「最小0か1か」も合わせて示すことがあります。たとえば「注文が0件の顧客もありうる(0以上)」のか「必ず1件以上ある」のかを区別すると、より正確な設計になります。記法が違っても「いくつ対いくつか」を伝える目的は同じです。
多重度を正しく決めることは、データベース設計の土台です。なぜなら、対応関係によって「表をどう作り、どう結ぶか」が変わるからです。
多重度ごとの表の作り方は次のようになります。
・1対多:「多」側の表に「1」側の主キーを外部キーとして持たせて結ぶ(最も基本)
・1対1:どちらかの表に相手の主キーを持たせる(1つの表にまとめることも多い)
・多対多:そのままでは表にできないので、間に連関エンティティ(中間テーブル)を置いて「1対多」を2つに分解する
とくに見落としやすいのが多対多です。「学生と科目」「商品とタグ」のように、どちらも複数とつながる関係を見つけたら、間に「履修」「商品タグ」などの連関エンティティを挟むのが定石です。多重度を見誤ると、データが重複したり、必要な情報を記録できなくなったりするため、設計の最初にしっかり確認します。上のツールのSTEP5で、多対多が1対多2つに分解される様子を確認できます。
多重度を最初に決める理由は、表(テーブル)の構造が多重度によって根本から変わるからです。後から直すと、データをすべて作り直す大工事になります。
多重度によって設計がどう変わるかをまとめると次のとおりです。
・1対多:「多」側のテーブルに「1」側の識別番号(主キー)を列として追加するだけで結べる。テーブルは2つのまま
・多対多:「誰と誰がつながっているか」を記録する中間テーブルを別に1つ追加しなければならない。テーブルが3つになる
・1対1:どちらかに相手の識別番号を追加するか、2つを1つにまとめることが多い
身近な例で考えると、間取り図を最初に決めてから家を建てるのと同じです。後から「壁を増やしたい」と言うと大改修になります。データベースも、多重度という間取りを設計の最初に確定しておくことで、後から無駄な修正をせずに済みます。上のツールで各パターンの対応線の本数を確認しながら、この違いを視覚的につかみましょう。
多重度を決めたら、次はテーブル(表)でその関連を実装します。1対多の関連を表す最も基本の方法が外部キー(Foreign Key)です。
外部キーの仕組みをひとことで言うと、「多」側のテーブルに「1」側の識別番号をコピーして持たせることです。
・「1」側(顧客):「顧客ID(主キー)」でそれぞれの顧客を識別する
・「多」側(注文):「顧客ID(外部キー)」列を追加し、「この注文は顧客C001のもの」と記録する
・外部キーの値は必ず「1」側に存在する識別番号でなければならない(存在しない顧客IDは入れられない)
身近な例で考えると、注文票に「担当者コード」を書くのに似ています。社員名簿(顧客テーブル)に存在するコードだけを書けるので、存在しない人物への紐付けを防げます。このように外部キーはデータの「つながりの正確さ(整合性)」を守る仕組みです。上のツールで多重度の対応線を確認しながら、このつながり方のイメージをつかみましょう。