Разница между «один ко многим», «многие к одному» и «многие ко многим»? - PullRequest
118 голосов
/ 25 июня 2010

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

196 голосов
/ 12 ноября 2013

Похоже, что все отвечают One-to-many против Many-to-many:

Разница между One-to-many, Many-to-one и Many-to-Many составляет:

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

  • В One-to-many сторона many сохранит ссылку на сторону one.Хороший пример - «У человека много навыков».В этом случае Person - это одна сторона, а Skill - это сторона со многими.В таблице будет столбец person_id skills.

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

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

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

  • В Many-to-Many члены каждой партии могут содержать ссылку на произвольное число членовдругая сторона.Для этого используется справочная таблица .Примером этого являются отношения между врачами и пациентами.Врач может иметь много пациентов и наоборот.
141 голосов
/ 25 июня 2010

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

  • Однонаправленный : Человек может напрямую ссылаться на Навыки через свой Набор
  • Двунаправленный : у каждого «дочернего» навыка есть один указатель на Персона (которая не указана в вашем коде)

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

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

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

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

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

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

33 голосов
/ 03 июня 2013

1) Круги - это сущности / POJOs / Beans

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

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

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

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

7 голосов
/ 25 июня 2010

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

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

*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. 
1 голос
/ 25 июня 2010

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



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

0 голосов
/ 25 июня 2010

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

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

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

class PersonSkill 
{
    Person person;
    Skill skill;    
}

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

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

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

Удачи!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...