Учение - OneToOne Однонаправленный против OneToOne Двунаправленный
I joust начал играть с библиотекой ORM доктрины, а Im узнал обо всех связях между таблицами.
Итак, я застрял в различиях в однонаправленном и двунаправленном отношениях.
Как я понял, однонаправленное отношение имеет первичный ключ только с одной стороны, и эта сторона владеет правой стороной?
А двунаправленное отношение имеет первичный ключ в обеих таблицах, и поэтому вы можете иметь отношение с обеих сторон и устанавливать ограничения с обеих сторон.
Теперь я читаю документацию Doctrine об отношениях и там у вас есть:
Unidirectional и Bidirectional.
Но они создают один и тот же SQL, и те же таблицы с теми же основными ключами и ограничениями. Поэтому я не вижу в этих двух различиях. И оба примера имеют первичный ключ с одной стороны.
Как я понял, истинное отношение двунаправленного должно иметь первичные ключи в обеих таблицах, указывающие на другую таблицу вправо? И с данным примером документации Doctrine это не так. Оба примера дают один и тот же результат и одинаковы.
Итак, что я сделал, это, скажем, у меня есть User and Card Entity и хочу, чтобы отношение было односторонним двунаправленным.
/**
* @Entity
* @Table(name="users")
*/
class User
{
/**
* @Id
* @GeneratedValue
* @Column(type="bigint")
*/
protected $id;
/**
* @OneToOne(targetEntity="Card", mappedBy="User")
* @JoinColumn(name="card_id", referencedColumnName="id")
*/
protected $card;
/**
* @Column(name="user_name", type="string")
*/
protected $userName;
/**
* @Column(name="user_pass", type="string")
*/
protected $userPass;
}
/**
* @Entity
* @Table(name="cards")
*/
class Card
{
/**
* @Id
* @GeneratedValue
* @Column(type="bigint")
*/
protected $id;
/**
* @OneToOne(targetEntity="User", inversedBy="Card")
* @JoinColumn(name="user_id", referencedColumnName="id")
*/
protected $user;
/**
* @Column(name="post_title", type="string")
*/
protected $cardType;
}
Разница здесь заключается в том, что я написал @JoinColumn в обоих объектах/сущностях. И в Доктрине есть только один.
Теперь я получаю то, что, по моему мнению, является двунаправленным отношением. Если я посмотрю на диаграмму EER, я вижу одну строку, указывающую от пользователя к карте, а другую от карты к пользователю.
Итак, я понял это правильно?
Неправильная документация Doctrine?: D
Как отношение двунаправленного отношения OneToOne будет выглядеть в диаграмме EER?
Спасибо!
Ответы
Ответ 1
Единственное различие заключается в интерфейсе класса PHP, то есть в присутствии или отсутствии свойства, которое указывает владельцу (например, свойство $customer
в упомянутом примере Doctrine). Другими словами, Доктрина просто должна знать, следует ли ей заботиться об одном свойстве ($shipping
) или двух свойствах ($cart
и $customer
). Другого разницы нет. Поэтому код SQL тот же (поскольку одного внешнего ключа достаточно для представления любого отношения 1: N), и нет никакой разницы в диаграмме EER ни (поскольку в EER вы обычно не решаете такие детали реализации, связанные с PHP).
Ответ 2
Однонаправленные и двунаправленные не имеют ничего общего с фоновым алгоритмом, как создавать эти соединения на уровне базы данных.
Все, о чем они говорят, это то, как можно использовать соединения. В однонаправленном отношении вы можете получить доступ к цели только с одного сайта. Двунаправленная связь позволяет вызвать соединение с двух (обеих) сторон.
Итак, в unidir. относительный model_a может перейти к model_b, но model_b не может получить model_a (без дополнительной работы).
Если вы сейчас используете bidir. rel обе модели могут без проблем получать доступ друг к другу
В терминах доктрины однонаправленное отношение определяет
$modelA->getModelB()
, но не метод $modelB->getModelA()
, тогда как двунаправленное отношение определяет оба метода (или аксессоры, однако вы хотите их называть)
в диаграмме uml это будет выглядеть так:
unidirectional
modelA --X------> modelB
bidirectional
modelA <--------> modelB