代码之家  ›  专栏  ›  技术社区  ›  Ian Dallas

一对多、多对一和多对多的区别?

  •  107
  • Ian Dallas  · 技术社区  · 14 年前

    好吧,这可能是一个微不足道的问题,但我很难想象和理解这些差异,以及何时使用它们。我还不清楚单向映射和双向映射等概念如何影响一对多/多对多关系。我现在正在使用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
    }
    

    在这种情况下,我会得到什么样的映射?对于这个特定的例子的答案是肯定的,但是我也非常希望了解什么时候使用一对多和多对多,什么时候使用连接表和连接列,以及单向和双向。

    6 回复  |  直到 7 年前
        1
  •  132
  •   Dave    8 年前

    一对多 :一个人有许多技能,一项技能在两个人之间不能重复使用。

    • 单向的 :一个人可以通过其集合直接引用技能
    • 双向的 :每个“儿童”技能都有一个指针指向 人员(代码中未显示)

    多对多 :一个人有许多技能,一项技能在两个人之间重复使用

    • 单向的 :一个人可以通过其集合直接引用技能
    • 双向的 :一项技能有一组与之相关的人。

    在一对多关系中,一个对象是“父对象”,一个对象是“子对象”。父级控制子级的存在。在“多对多”中,任何一种类型的存在都依赖于它们两个类型之外的某个类型(在更大的应用程序上下文中)。

    你的主题(领域)应该决定关系是一对多还是多对多——然而,我发现使关系单向或双向是一个工程决策,它权衡了内存、处理、性能等。

    令人困惑的是,一个多对多的双向关系不需要是对称的!也就是说,一群人可以指向一种技能,但这种技能不需要仅仅与那些人相关。通常是这样,但这种对称性不是一个要求。以爱为例,它是双向的(“我爱”,“爱我”),但往往是不对称的(“我爱她,但她不爱我”)!

    所有这些都得到了Hibernate和JPA的良好支持。请记住,Hibernate或任何其他ORM在管理双向多对多关系时都不会对维护对称性大呼小叫……这完全取决于应用程序。

        2
  •  177
  •   Community c0D3l0g1c    7 年前

    看起来每个人都在回答 One-to-many VS Many-to-many :

    两者之间的区别 一对多 , Many-to-one Many-to-Many 是:

    一对多 VS 多对一 是一个观点问题 . Unidirectional VS Bidirectional 不会影响映射,但会对如何访问数据产生影响。

    • 一对多 这个 many 我方将保留 one 一边。一个很好的例子是“一个人有很多技能”。在这种情况下 Person 是一边,而且 Skill 是多方面的。会有一个专栏 person_id 在桌子上 skills .

    单向的 班级将有 List<Skill> skills 但是 技能 不会有 Person person . 在 双向的 二者都 属性被添加,它允许您访问 给定一个 技能(即 skill.person )

    • 多对一 多方面将是我们的参考点。例如,“用户有地址”。在我们的系统中,许多用户可能共享一个地址(例如,许多人可能共享相同的块号)。在这种情况下, address_id 列中 users 表将由多个共享 用户 排。在这种情况下,我们说 用户 addresses 多对一 关系。

    单向的 User 将有 Address address . 双向的 会有额外的 List<User> users Address 班级。

    • 多对多 每一方的成员都可以参考另一方任意数量的成员。为了达到这个目的 look up table 使用。例如,医生和病人之间的关系。医生可以有很多病人,反之亦然。
        3
  •  31
  •   mixel    7 年前

    1)圆圈是实体/pojos/bean

    2)deg是度的缩写,如图(边数)中所示。

    pk=主键,fk=外键

    注意度数和边名之间的矛盾。许多对应于degree=1,而一个对应于degree>1。

    在图中(边数)

    pk=主键,fk=外键

    注意度数和边名之间的矛盾。许多对应于degree=1,而一个对应于degree>1。

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

        4
  •  6
  •   alejandrobog    14 年前

    请看这篇文章: Mapping Object Relationships

    映射时需要关注两类对象关系。第一类基于多重性,包括三种类型:

    *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. 
    

    第二类基于 方向性,它包含两个 类型,单向关系 以及双向关系。

    *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. 
    
        5
  •  1
  •   msshapira    14 年前

    这可能需要一个多对多关系船,如下所示

    
    
    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,但是它也可以在没有…

        6
  •  0
  •   jyoungdev Thilo    14 年前

    首先,阅读所有的印刷品。注意,nHibernate(因此,我假设也是Hibernate)关系映射与db和对象图映射有一个有趣的对应关系。例如,一对一关系通常实现为多对一关系。

    其次,在我们告诉您应该如何编写O/R映射之前,我们还必须查看您的DB。尤其是,一项技能能被多人拥有吗?如果是这样的话,你有一种多对多的关系;否则,就是多对一的关系。

    第三,我不希望直接实现多对多的关系,而是在域模型中建模“join table”——即,将其视为一个实体,如下所示:

    class PersonSkill 
    {
        Person person;
        Skill skill;    
    }
    

    那你看到你有什么了吗?你有两个一对多的关系。(在这种情况下,个人可能拥有一系列的个人技能,但不会拥有一系列的技能。)然而,有些人更喜欢使用多对多的关系(人与技能之间);这是有争议的。

    第四,如果你确实有双向关系(例如,人不仅有一系列的技能,而且技能也有一系列的人),那么nhibernate会有。 在BL中为您强制执行双向性;它只理解关系的双向性,以实现持久性目的。

    第五,在NHibernate(我假设是Hibernate)中,多对一要比一对多(集合映射)更容易正确使用。

    祝你好运!