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

Когда стоило бы поддерживать обратную связь в Doctrine2?

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

Я говорю это, потому что кажется, что вы часто захотите перейти с одной стороны ассоциации "один-ко-многим", а не со стороны "Многие". Например, я хотел бы получить все Пользовательские PhoneNumbers, а не получать все активные PhoneNumbers и связанные с ними User. Это становится более важным, когда вам нужно пересекать несколько отношений "один ко многим", например. если вы хотите видеть всех пользователей с MissedCall за последние два дня (MissedCall- > PhoneNumber- > User).

Так будет выглядеть простой случай с обратной ассоциацией:

SELECT * FROM User u
LEFT JOIN u.PhoneNumbers p WITH p.active

Было бы более разумным, если бы в DQL можно было перейти к заданному отношению в обратном направлении, например, следующий необработанный SQL:

SELECT * FROM User u
LEFT JOIN PhoneNumber p ON p.User_id = u.id AND p.active

Может кто-нибудь объяснить, почему они дают этот совет, и в каких случаях это стоит игнорировать?

- Изменить -

Если есть смягчающие факторы или другие обходные пути, пожалуйста, дайте мне простой примерный код или ссылку.

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

4b9b3361

Ответ 1

Используя Doctrine, я определяю отношения только тогда, когда они нужны. Это означает, что все определенные отношения действительно используются в базе кода.

Для проектов с большой командой, работающей в разных областях проекта, не каждый будет привык к Доктрине, ее текущей конфигурации и нетерпимым/ленивым отношениям загрузки. Если вы определяете двунаправленные отношения, где они не являются существенными и, возможно, не имеют смысла, это может потенциально привести к дополнительным запросам для данных, которые:

  • не может быть использован
  • может быть выбран ранее

Определение только важных отношений позволит вам более эффективно контролировать, как вы и ваша команда проходите через ваши данные, и уменьшайте дополнительные или чрезмерно большие запросы.

Обновлено 22/08/2011

Под существенными отношениями я имею в виду те, которые вы используете. Не имеет смысла определять отношения, которые вы бы не использовали. Например:

  • \Entity\Post имеет определенное отношение как к \Entity\User, так и к \Entity\Comment
    • Используйте $post->user, чтобы получить автора
    • Используйте $post->comments, чтобы получить все комментарии
  • \Entity\User имеет определенное отношение как к \Entity\Post, так и к \Entity\Comment
    • Используйте $user->posts, чтобы получить все сообщения пользователя
    • Используйте $user->posts, чтобы получить все комментарии пользователей
  • \Entity\Comment имеет отношение только к \Entity\User
    • Используйте $comment->user, чтобы получить автора
    • Невозможно использовать $comment->post, поскольку я не получаю сообщение, которое оно принадлежит в моем приложении.

Я бы не думал о них как о "обратных" отношениях. Думайте о них как о "двунаправленном", если использовать данные в обоих направлениях. Если это не имеет смысла или вы не будете использовать данные таким образом, не определяйте его.

Надеюсь, это имеет смысл

Ответ 2

Я думаю, что это большой вопрос, и я с нетерпением жду ответа других.

Как правило, я интерпретировал совет, который вы указали в нижеследующем правиле:

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