Подтвердить что ты не робот

Учение - 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?

Спасибо!

4b9b3361

Ответ 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