Разница между "Один ко многим", "много к одному" и "много ко многим"?

Ok так что это, вероятно, тривиальный вопрос, но у меня возникли проблемы с визуализацией и пониманием различий и когда использовать каждый. Я также немного не понимаю, как концепции, такие как однонаправленные и двунаправленные отображения, влияют на отношения "один ко многим" / "много ко многим". Я использую 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 ответов


один-ко-многим: один человек имеет много навыков, навык не используется повторно между людьми

  • однонаправленный: человек может напрямую ссылаться на навыки через свой набор
  • двунаправленный: каждый навык" ребенок " имеет один указатель на Person (который не отображается в вашем коде)

многие-ко-многим: один человек имеет много навыков, умения используют Персона(ы)

  • однонаправленный: человек может напрямую ссылаться на навыки через свой набор
  • двунаправленный: навык имеет набор людей, которые относятся к нему.

в отношениях "один ко многим" один объект является "родителем", а другой - "ребенком". Родитель контролирует существование ребенка. Во многих-ко-многим существование любого типа зависит от чего-то вне их обоих (в более крупном контекст приложения.)

ваш предмет (домен) должен диктовать, является ли отношение "один ко многим" или "много ко многим", однако я считаю, что однонаправленное или двунаправленное отношение-это инженерное решение, которое торгует памятью, обработкой, производительностью и т. д.

Что может быть запутанным, так это то, что двунаправленное отношение "многие ко многим" не должно быть симметричным! То есть куча людей могла бы указать на какой-то навык, но навык нужен не относиться только к этим людям. Как правило, это так, но такая симметрия не является требованием. Возьмем, к примеру, любовь-она двунаправленная ("я-люблю", "любит-меня"), но часто асимметричная ("я люблю ее, но она меня не любит")!

все они хорошо поддерживаются Hibernate и JPA. Просто помните, что Hibernate или любой другой ORM не дает ухо о поддержании симметрии при управлении двунаправленными отношениями "многие ко многим"...это все зависит от приложения.


похоже, все отвечает One-to-many vs Many-to-many:

разницу между One-to-many, Many-to-one и Many-to-Many - это:

One-to-many vs Many-to-one - это вопрос перспективы. Unidirectional vs Bidirectional не повлияет на отображение, но будет иметь значение о том, как вы можете получить доступ к данным.

  • на One-to-many на many сторона будет держать ссылку one стороне. Хороший пример- "у человека много навыков". В этом дело Person является одной стороной и Skill это много сторон. Будет колонка person_id в таблице skills.

на однонаправленный Person класса List<Skill> skills но Skill не будет Person person. В двунаправленный как свойства добавляются, и это позволяет получить доступ к Person дали умение (то есть skill.person).

  • на Many-to-one много сторона будет нашей точкой зрения ссылка. Например, "у пользователя есть адрес". В нашей системе многие пользователи могут иметь общий адрес (например, несколько человек могут иметь один и тот же номер блока). В этом случае на users таблица будет разделена более чем одним users строк. В этом случае мы говорим, что users и addresses есть Many-to-one отношения.

на однонаправленный a User будет Address address. двунаправленный будет иметь дополнительный List<User> users на Address класса.


1) круги являются сущностями / POJOs / Beans

2) deg-это аббревиатура степени, как на графиках (количество ребер)

PK=первичный ключ, FK = внешний ключ

обратите внимание на противоречие между степенью и название стороны. Много соответствует степени=1, а соответствует степени >1.

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


взгляните на эту статью: Отображение Отношений Объектов

существует две категории отношений объектов,которые необходимо учитывать при сопоставлении. Первая категория основана на множественности и включает в себя три типа:

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

Это, вероятно, вызовет корабль отношений "многие ко многим" следующим образом



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, но это будет возможно также без...


прежде всего, прочитайте все мелким шрифтом. Обратите внимание, что NHibernate (таким образом, я предполагаю, Hibernate) реляционное отображение имеет забавное соответствие с отображением графов БД и объектов. Например, отношения "один к одному" часто реализуются как отношения "много к одному".

во-вторых, прежде чем мы сможем сказать вам, как вы должны написать свою карту O/R, мы также должны увидеть вашу БД. В частности, может ли один навык принадлежать нескольким людям? Если это так, у вас есть много-ко-многим отношения; в противном случае, это много-к-одному.

в-третьих, я предпочитаю не реализовывать отношения "многие ко многим" напрямую, а вместо этого моделировать "таблицу соединений" в вашей модели домена, т. е. рассматривать ее как сущность, например:

class PersonSkill 
{
    Person person;
    Skill skill;    
}

затем вы видите, что у вас есть? У вас два отношения "один ко многим". (В этом случае человек может иметь коллекцию PersonSkills, но не будет иметь коллекцию навыков.) Тем не менее, некоторые предпочтут использовать отношения "многие ко многим" (между личностью и умением); это спорно.

В-четвертых, если у вас есть двунаправленные отношения (например, не только у человека есть коллекция навыков, но и у навыка есть коллекция людей), NHibernate делает не принудительно двунаправленность в вашем BL для вас; он понимает только двунаправленность отношений для целей сохранения.

В-пятых, многие-к-одному намного проще правильно использовать в NHibernate (и я предполагаю, что Hibernate) чем один-ко-многим (сопоставление коллекция).

удачи!