できるエンジニアになるためのちょい上DB術/第2章 概念設計
2.3 概念設計の手順(2/3)
リレーションのパターン
リレーションの代表的な種類がいくつか理解できたところで、具体的なパターン例をいくつか挙げてみましょう。
セット商品や部品表の特徴は、セット商品や部品の組み合わせでできた他の部品が、さらにほかの商品や部品の一部として組み込まれる可能性があるという点です。
このため、セット商品と商品の間のリレーションは多対多になり、それを分解すると、図2-15の下側の図のようになります。
具体的には、1つ1つの製品または部品の組み合わせによる製品が左側のエンティティのオカレンスにあたり、その製品がどのような部品の組み合わせでできているかという構成が右側のエンティティで管理されます。
具体的には図2-16のオカレンスとオカレンスをイメージ化した図で確認してみてください。
部品表の具体的な見方を説明します。製品表の一意識別子は製品番号です。
構成表の一意識別子は、構成される製品番号と、それを構成する1つの部品番号の組み合わせになります。
製品番号A000lという製品の構成は、構成表の1行目と2行目を見るとわかります。
構成表には、構成する部品の数量も管理しています。
製品番号B000lという製品の構成は、構成表の3行目から5行目を見るとわかりますが、部品となっている製品A000lが2個、E000lが1個、D000lが3個で構成されています。
多対多のリレーションシップ
リレーションの代表的な種類がいくつか理解できたところで、具体的なパターン例をいくつか挙げてみましょう。
このER図上で、たとえば、次のような情報はどこで管理できるのでしょうか。
これは、プロジェクトを管理するエンティティでも、社員を管理するエンティティでも管理することができない情報です。
1つのプロジェクトに複数の社員が対応するのであれば、その値は1つのプロジェクトに複数対応します。
1人の社員に複数のプロジェクトが対応するのであれば、1人の社員に複数の値が対応するからです。
そこで、多対多のリレーションシップをもつ2つのエンティティの間で管理すべき項目は、間に1つエンティティを設けてそこで管理することを考えます。
このようなエンティティを交差エンティティと呼びます。
交差エンティティの一意識別子は、その両端のエンティティの一意識別子の組み合わせを考えます。
そうすることによって、交差エンティティ「プロジェクト構成員管理」では、ある社員があるプロジェクトに参画し始めた時期や、役割を管理することができます。
このように、多対多のリレーションシップが存在した場合は、間に交差エンティティを設け、1対多のリレーションに分解します。理由は以下のとおりです。
- そのままではデータベース表に変換できない
- 両端のエンティティで管理できない属性がでてくる
多対多のリレーションシップを分解して、交差エンティティを設ける手順は、以下のとおり、ある程度一般化することができます。
- 1.多対多のリレーションシップをもつエンティティ間に交差エンティティを追加する
- 2.交差エンティティの識別子として、両端のエンティティの一意識別子を組み合わせた複合一意識別子を指定する
- 3.交差エンティティで管理すべき、その他の属性がないか検討する
- 4.交差エンティティと元のエンティティの間のリレーションを検討する
図2-18のプロジェクトと社員の間のリレーションの場合、以下のように説明できます
したがって、多対多のリレーションであることがわかります。
- 1.間に交差エンティティ「プロジ工クト構成員管理」を設ける
- 2.このエンティティの一意識別子はプロジ工クトIDと社員IDの複合一意識別子とする
- 3.管理すべき属性として、構成員がそのプロジ工クトに参画し始めた日付、プロジ工クトでの役割などを管理することができる
- 4.リレーションは、交差エンティティから元のエンティティに対しては、多対1で1側が必須。多側は任意
その他のエンティティとリレーション
エンティティとリレーションの少し変わった表現をするパターンを2つ紹介します。
- スーパータイプ/サブタイプ
- 再帰リレーション
スーパータイプ/サブタイプ
エンティティを考える際、同じ識別子をもち、属性は一部異なるオカレンスをもついくつかのエンティティが抽出される場合があります。
それらのエンティティ間では、共通のデータ項目をもつエンティティと、各エンティティに固有のデータ項目のみをもつエンティティに分けることができます。
共通のデータ項目、リレーションをもつエンティティをスーパータイプ、それぞれ国有の属性をもつエンティティをサブタイプと呼びます。
図2-19は、社員の職種を管理するエンティティで、社員の共通管理項目を「社員」スーパータイプ、職種ごとの管理項目をサブタイプで表している図です。
特徴 | 説明 |
---|---|
継承 | サブタイプはスーパータイプのすべての属性とリレーションシップを受け継ぐ |
特殊化 | サブタイプはスーパータイプに属性やそのサブタイプのみに関係するリレーションシップを追加する |
サブタイプ | 実装時、スーパータイプにサブタイプの分類を特定するための属性を識別子としてもたせる場合がある |
排他関係 | すべてのオカレンスはいずれかのサブタイプに属するが、重複することはない |
表2-2 サブタイプの特徴
こうしてみてくると、ほとんどのエンティティがスーパータイプ/サブタイプで表すことができるように思えてくるのですが、スーパータイプ/サブタイプで表すかどうかは、次の点に注意して、その必要があるかを判断してください。
共通性が高いが違いがあり、その違いをシステムとして管理する必要がある場合にスーパータイプ/サブタイプを使用します。
たとえば、企業の売掛処理をする場合に、各支店で生じた売掛金額の総計が与信限度額を超えていないかを管理するような場合を考えてみましょう。
企業として管理される総計の与信限度額と各支店の売掛金額総計はスーパータイプで、各支店の売掛金額はサブタイプで管理します。
概念設計では、スーパータイプ/サブタイプとして表すべきエンティティを抽出しておきます。
実際にどのような表として実装するかは、物理設計のフェーズで考えます。
再帰リレーション
同一のエンティティを再帰的に結んでいるリレーションのことを指します。
このリレーションは、あるエンティティオカレンスから、同じエンティティに属する別のエンティティオカレンスとの間に何らかの関連をもつことを示します。
なお、再帰リレーションを分析する際、オプショナリティは両側で任意になります。
これは、実際にオカレンスを挿入する場合を考えてみるとわかるのですが、いずれか一方でも必須のリレーションがあると、最初にオカレンスを挿入する際、同時に自身のオカレンスとリレーションの対象先のオカレンスの最低でも2オカレンスを挿入する必要が生じてしまいます。
しっかり分析すると、再帰リレーションの両端は常にオプションになっているはずです。
リレーションの実装と制約
以上がエンティティとリレーションに関する概要説明です。
次に、エンティティとリレーションが実装時にはどのように表現されるのかを見てみましょう。
すべてのリレーションが1対多に分解された後、リレーションの多側のエンティティには1側の一意識別子が属性として追加されます。
この属性を外部キーと呼びます。
外部キーに値が入ることによって、多側のオカレンスがどの1側のオカレンスに対応するのかを知ることができます。
以下の例は、2つのエンティティ間にリレーションシップがあり、それを表現するために多側のオカレンスの属性に1側の一意識別子を外部キーとしてとり込んでいます。
また、リレーションのオプショナリティから、オカレンスの生成時や削除時の制約(ルール)を読み取ることができます。
図2-21のようにリレーションの1側が必須の場合、多側のオカレンスが生成される際、外部キーの値は、もう一方のエンティティの識別子の値として、あらかじめ存在している必要があることを示しています。
また、1側の顧客オカレンスを削除するとき、顧客が注文していた注文オカレンスが残っていれば、その顧客オカレンスは削除はできないことがわかります。
もう1つ、特別なリレーションを見てみましょう。
1側が必須の場合、1側の一意識別子を外部キーとし、かつ多側の一意識別子の一部とする場合があります。
この場合、多側のエンティティを従属エンティティと呼びます。
このような場合、オカレンス生成時のルールとして以下のことが読み取れます。
- 1側のオカレンス「注文」を作成するとき、必ず「注文明細」のオカレンスが1つ以上存在する必要がある
- 注文明細を作成するときには、必ずそれに対応する注文が存在する
また、削除時のルールとしては、以下のようなことがいえます。
- 注文を削除すると、それに対応する明細はすべて削除される
- 注文明細を削除するときには、そのオカレンスが対応する注文の最後の明細であれば、注文も削除される
このような場合、2つのエンティティはライフサイクルが同じであることがわかります。
エンティティとリレーションの全体像をつかんだところで、次に属性について見てみましょう。
解説トレーナー