web-dev-qa-db-ja.com

1対多、多対1、多対多の違いは?

わかりましたので、これはおそらく些細な質問ですが、違いとそれぞれをいつ使用するかを視覚化して理解するのに苦労しています。また、単方向および双方向マッピングのような概念が1対多/多対多の関係にどのように影響するかについても少し不明瞭です。現在Hibernateを使用しているため、ORMに関連する説明があれば役立ちます。

例として、次のセットアップがあるとします。

public class Person{
    private Long personId;
    private Set<Skill> skills;
    //Getters and setters
}

public class Skill{
    private Long skillId;
    private String skillName;
    //Getters and setters
}

この場合、どのようなマッピングがありますか?この特定の例に対する回答は間違いなく高く評価されますが、1対多および多対多のどちらを使用するか、および結合テーブルと結合列、および単方向と双方向を使用するタイミングの概要も非常に気に入っています。

121
Ian Dallas

1対多:1人の人間に多くのスキルがあり、スキルは個人間で再利用されません

  • 単方向:個人は、そのセットを介してスキルを直接参照できます
  • 双方向:各「子」スキルには、Personに戻る単一のポインターがあります(コードには表示されません)

多対多:1人の人に多くのスキルがあり、スキルは人の間で再利用されます

  • 単方向:個人は、そのセットを介してスキルを直接参照できます
  • 双方向:スキルには、関連する個人のセットがあります。

1対多の関係では、1つのオブジェクトが「親」で、もう1つのオブジェクトが「子」です。親は子の存在を制御します。多対多では、どちらかのタイプが存在するかどうかは、両方の外側の何か(より大きなアプリケーションコンテキスト内)に依存します。

主題(ドメイン)は、リレーションシップが1対多または多対多であるかどうかを決定する必要があります-ただし、リレーションシップを単方向または双方向にすることは、メモリ、処理、パフォーマンスをトレードオフするエンジニアリング上の決定であることがわかりますなど.

紛らわしいのは、多対多の双方向の関係が対称である必要がないことです!つまり、多くの人々がスキルを指すことができますが、スキルはそれらの人々だけに関連する必要はありません。通常はそうなりますが、そのような対称性は必須ではありません。たとえば、愛を考えてみましょう。双方向(「I-Love」、「Loves-Me」)ですが、多くの場合非対称(「私は彼女を愛していますが、彼女は私を愛していません」)です。

これらはすべて、HibernateおよびJPAによって十分にサポートされています。 Hibernateまたは他のORMは、双方向の多対多のリレーションシップを管理する際に対称性を維持することについては気に留めないことを覚えておいてください...それはすべてアプリケーション次第です。

144
HDave

誰もがOne-to-manyMany-to-manyに答えているようです:

One-to-manyMany-to-one、およびMany-to-Manyの違いは次のとおりです。

One-to-many vs Many-to-oneは視点の問題ですUnidirectional vs Bidirectionalはマッピングに影響しませんが、データへのアクセス方法に違いが生じます。

  • One-to-manyでは、many側はone側の参照を保持します。良い例は「人は多くのスキルを持っている」です。この場合、Personは片側で、Skillは多側です。テーブルskillsには列person_idがあります。

unidirectionalPersonクラスにはList<Skill> skillsがありますが、SkillにはPerson personがありません。 bidirectionalで両方のプロパティが追加され、スキル(つまりskill.person)が与えられたPersonにアクセスできます。

  • Many-to-oneでは、多くの側面が参照ポイントになります。たとえば、「ユーザーにはアドレスがあります」。このシステムでは、多くのユーザーがアドレスを共有する場合があります(たとえば、多くの人が同じブロック番号を共有する場合があります)。その場合、usersテーブルのaddress_id列は、複数のusers行で共有されます。この場合、usersaddressesMany-to-one関係にあると言います。

unidirectionalでは、UserAddress addressになります。 Bidirectionalには、AddressクラスにList<User> usersが追加されます。

  • Many-to-Manyでは、各パーティのメンバーは、相手の任意の数のメンバーへの参照を保持できます。これを実現するために、 ルックアップテーブル が使用されます。この例は、医師と患者の関係です。医師は多くの患者を抱えることがあり、その逆もあります。
202

1)円は、エンティティ/ POJO/Beanです

2)degは、グラフのように次数を表す略語です(エッジの数)

PK =プライマリキー、FK =外部キー

学位とサイドの名前の矛盾に注意してください。多くは次数= 1に対応し、一方は次数> 1に対応します。

Illustration of one-to-many many-to-one

33
jhegedus

この記事をご覧ください: マッピングオブジェクトの関係

マッピングの際に考慮する必要があるオブジェクトの関係には2つのカテゴリがあります。最初のカテゴリは多重度に基づいており、3つのタイプが含まれています。

*One-to-one relationships.  This is a relationship where the maximums of each of its multiplicities is one, an example of which is holds relationship between Employee and Position in Figure 11.  An employee holds one and only one position and a position may be held by one employee (some positions go unfilled).
*One-to-many relationships. Also known as a many-to-one relationship, this occurs when the maximum of one multiplicity is one and the other is greater than one.  An example is the works in relationship between Employee and Division.  An employee works in one division and any given division has one or more employees working in it.
*Many-to-many relationships. This is a relationship where the maximum of both multiplicities is greater than one, an example of which is the assigned relationship between Employee and Task.  An employee is assigned one or more tasks and each task is assigned to zero or more employees. 

2番目のカテゴリは方向性に基づいており、単方向の関係と双方向の関係の2つのタイプが含まれています。

*Uni-directional relationships.  A uni-directional relationship when an object knows about the object(s) it is related to but the other object(s) do not know of the original object.  An example of which is the holds relationship between Employee and Position in Figure 11, indicated by the line with an open arrowhead on it.  Employee objects know about the position that they hold, but Position objects do not know which employee holds it (there was no requirement to do so).  As you will soon see, uni-directional relationships are easier to implement than bi-directional relationships.
*Bi-directional relationships.  A bi-directional relationship exists when the objects on both end of the relationship know of each other, an example of which is the works in relationship between Employee and Division.  Employee objects know what division they work in and Division objects know what employees work in them. 
7
alejandrobog

これはおそらく次のような多対多の関係シップを必要とします



public class Person{

    private Long personId;
    @manytomany

    private Set skills;
    //Getters and setters
}

public class Skill{
    private Long skillId;
    private String skillName;
    @manyToMany(MappedBy="skills,targetClass="Person")
    private Set persons; // (people would not be a good convenion)
    //Getters and setters
}

あなたはjoinTable + JoinColumnを定義する必要があるかもしれませんが、それがなくても動作する可能性があります...

1
msshapira

まず第一に、すべての細かい活字を読んでください。 NHibernate(したがって、Hibernateも同様です)リレーショナルマッピングは、DBおよびオブジェクトグラフマッピングとおもしろく対応していることに注意してください。たとえば、1対1の関係は、多くの場合、多対1の関係として実装されます。

第二に、O/Rマップをどのように記述するかを伝える前に、DBも確認する必要があります。特に、単一のスキルを複数の人が所有できますか?もしそうなら、あなたは多対多の関係を持っています。それ以外の場合は、多対1です。

第三に、多対多のリレーションシップを直接実装するのではなく、ドメインモデルで「結合テーブル」をモデル化することを好みます。つまり、次のようにエンティティとして扱います。

class PersonSkill 
{
    Person person;
    Skill skill;    
}

次に、あなたが持っているものを見ますか? 2つの1対多の関係があります。 (この場合、PersonにはPersonSkillのコレクションがありますが、Skillのコレクションはありません。)ただし、一部のユーザーは多対多の関係(PersonとSkillの間)を使用することを好みます。これは議論の余地があります。

第4に、双方向の関係がある場合(たとえば、Personにスキルのコレクションがあるだけでなく、Skillにもコレクションがある)、NHibernateはnot BLの双方向性を強制します;永続化のために関係の双方向性のみを理解します。

5番目に、多対1(コレクションマッピング)よりもNHibernate(およびHibernateを想定)で多対1を正しく使用する方がはるかに簡単です。

幸運を!

0
apollodude217