Можете ли вы сказать мне, почему вы рекомендуете
отношения многих ко многим
Серия и События. Я понимаю, что это
потому что это «необязательно»
отношения, но я все еще немного
запутался, почему это делает его более
гибкий.
На самом деле, я запутался! В последнее время я много работал со смешанными формами наследования, где это имеет смысл из-за того, как вещи должны быть структурированы и максимально использовать ссылочную целостность. Я думаю, вы могли бы так же легко сделать следующее (что больше соответствует требованиям модели, как вы ее указали):
Event:
columns:
name: string(255)
venue_id: integer
series_id: {type: integer, default: null}
relations:
Venue:
local: venue_id
type: one
alias: Venue
foreign: id
foreignType: many
foreignAlias: Events
onDelete: CASCADE
Series:
local: series_id
type: one
alias: Series
foreign: id
foreignType: many
foreignAlias: Events
owningSide: true
onDelete: SET NULL
Venue:
columns:
name: string(255)
# other cols
Series:
columns:
name: string(255)
Тем не менее, использование m-m позволяет вам добавлять конкретные данные в refClass
или использовать несколько ссылочных классов по существу для одной и той же связи (именно здесь мне было удобно делать это таким образом в определенных ситуациях). Технически это более гибко, но по общему признанию, если то, что вы заявили, были вашими единственными требованиями, вам никогда не понадобится такая гибкость: -)
Кроме того, тот факт, что это
отношения многие ко многим,
требует дополнительного SeriesEvent
refClass, который будет определен?
Да.
Основываясь на этом, это правда?
необходимо определить
это дополнительное соединение всякий раз, когда
происходит много ко многим?
Ни одна доктрина не будет обрабатывать запросы автоматически каждый раз, когда вы вызываете метод доступа к коллекции. Однако в случаях как 1-m, так и m-m вам часто требуется добавить соединение в запрос, чтобы каждый раз, когда вы вызывали метод доступа, он не запрашивал базу данных снова. Например:
$events = Doctrine_Core::getTable('Event')->createQuery('e')->execute();
foreach($events as $event){
// each of the following will query the db so you have
// 2*(number of events) queries being issued to the DB in this loop
$series = $event->getSeries(); // this will join through the ref class automatically
$venue = $event->getVenue();
}
$events = Doctrine_Core::getTable('Event')->createQuery('e')
->leftJoin('e.Series s) // this will join with the ref class automatically
->leftJoin(e.Venue v)
->execute();
foreach($events as $event){
// because you explicitly joined the realtion all the data
// fetched at once, so this entire loop only uses 1 query.
$series = $event->getSeries();
$venue = $event->getVenue();
}
Я бы вообще не связывал Серию и Место проведения, потому что отношения всегда будут зависеть от События, поэтому корреляция не нужна. Вы можете просто добавить свои собственные аксессоры / мутаторы / искатели к своим классам, чтобы запросить третичные отношения или извлечь их из соответствующих связанных объектов. Кроме того, поскольку связь между Событием и Серией является необязательной, я бы использовал «многие ко многим», поскольку она обеспечивает большую гибкость.
Примерно так:
Event:
columns:
name: string(255)
venue_id: integer
relations:
Venue:
local: venue_id
type: one
alias: Venue
foreign: id
foreignType: many
foreignAlias: Events
onDelete: CASCADE
Series:
local: event_id
alias: Series
refClass: SeriesEvent
Venue:
columns:
name: string(255)
# other cols
Series:
columns:
name: string(255)
relations:
Events:
local: series_id
alias: Events
refClass: SeriesEvents
SeriesEvent:
columns:
event_id: {type: integer, primary: true}
series_id: {type: integer, primary: true}
relations:
Series:
local: series_id
type: one
alias: Series
foreign: id
foreignType: many
foreignAlias: SeriesEvents
onDelete: CASCADE
Event:
local: event_id
type: one
alias: Event
foreign: id
foreignType: many
foreignAlias: SeriesEvent
onDelete: CASCADE