@russeljo

Как понять ассоциации OneToMany(двунаправленная, однонаправленная) и OnDelete в Doctrine2?

Это небольшое вступление(можно пропустить), вопросы ниже(жирным шрифтом):

Я использую Zend Framework 3. И там Doctrine2.

Плаваю в этом вопросе.
Прочитал это https://www.doctrine-project.org/projects/doctrine...
Читаю это https://www.doctrine-project.org/projects/doctrine...

В этой статье Каскадное удаление данных есть понятие предок-потомок(родитель-ребенок) в отношении один-ко-многим. Потомок(ребенок) содержит внешний ключ, ссылается на родителя. Что интуитивно не сходится с доками доктрины(для меня по крайней мере). И там еще написано про нарушение ссылочной целостности при обновлении/удалении предка.

Из доков я понял:
- есть две стороны: owning side собственная(владелец, потомок) и inverse side обратная сторона(предок).
- owning side содержит внешний ключ

Owning side владеет отношением, владеет внешним ключем. Нет ключа - нет отношения.
И в случае двунаправленного отношения(bidirect) должно иметь атрибут inversedBy.
ManyToOne - это всегда сторона собственная.
OneToMany - это всегда сторона обратная.

Вопрос 1. В чем отличие однонаправленного ManyToOne и двунаправленного? В чем техническое отличие, ньюансы? Когда и какое выбрать?

Согласно докам генерируемые SQL запросы ничем не отличаются: добавляется поле и оно становится внешним ключем.
Отличаются только описание сущностей(полей php-классов).
//пример из доков - однонаправленное многие-к-одному
CREATE TABLE Address (
    id INT AUTO_INCREMENT NOT NULL,
    PRIMARY KEY(id)
) ENGINE = InnoDB;
CREATE TABLE User (
    id INT AUTO_INCREMENT NOT NULL,
    address_id INT DEFAULT NULL,
    PRIMARY KEY(id)
) ENGINE = InnoDB;
ALTER TABLE User ADD FOREIGN KEY (address_id) REFERENCES Address(id);

//пример из доков - двунаправленное один-ко-многим
CREATE TABLE Product (
    id INT AUTO_INCREMENT NOT NULL,
    PRIMARY KEY(id)
) ENGINE = InnoDB;
CREATE TABLE Feature (
    id INT AUTO_INCREMENT NOT NULL,
    product_id INT DEFAULT NULL,
    PRIMARY KEY(id)
) ENGINE = InnoDB;
ALTER TABLE Feature ADD FOREIGN KEY (product_id) REFERENCES Product(id);


По сути в админке это будет форма добавления записи в бд, где будет поле выбора(например для статьи выбрать язык). Я могу в сущностях описать однонаправленное или двунарправленное, что изменится? Может есть какие-то конкретные наглядные примеры.

Вопрос 2. Когда для статьи можно выбрать несколько категорий - какая это связь? ManyToMany - одна статья может иметь несколько категорий, в то же время одна категория может включать несколько статей. Или я что-то путаю? Здесь будет 3ья таблица?

Вопрос 3. Что означает cascade={"persist"}?
  • Вопрос задан
  • 594 просмотра
Пригласить эксперта
Ответы на вопрос 1
index0h
@index0h
PHP, Golang. https://github.com/index0h
В чем отличие однонаправленного ManyToOne и двунаправленного? В чем техническое отличие, ньюансы?


Пример - говно. У вас по сути идентичные отношения и в первом случае и во втором (со стороны БД). Вероятно имелось ввиду зависимости между вашими entity. Такое действительно можно сделать. Грубо говоря однонаправленная: User знает свой Address. Двунаправленная - User знает свой Address И Address соответствующих ему User знает свой. В БД действительно оба варианта выглядят одинаков. Разница в том, как с ними работает EntityManager.

Когда и какое выбрать?

По умолчанию задавать однонаправленную. Если вдруг понадобится - дорисуйте обратную связь.

Когда для статьи можно выбрать несколько категорий - какая это связь?

Много статей соответствуют многим категориям.

Здесь будет 3ья таблица?

Угу

Что означает cascade={"persist"}?

Выполняя EntityManager::persist($myEntityName), для зависимостей $myEntityName каскадом выполнится persist и руками это делать нет необходимости.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы