我正在尝试为我在Doctrine工作的项目设计一个模型,我想就如何定义不同的关系提出一些建议。
我有3张桌子
场地,系列赛和赛事
我的理解是,Venue和Series将是一个多对多的关系,因为许多场地可以有很多系列的事件,反之亦然。这种关系是“可选的”会改变一些事实吗?
我也理解这个活动与Venue和Series有一对多的关系,因为一个Venue可以有很多活动,一个系列可以有很多活动,但一个活动只能有一个活动。
我是否以正确的方式看待这一点,并且任何人都可以建议在Doctrine中定义此方法的最佳方法吗?
答案 0 :(得分:2)
你能告诉我你为什么推荐一个 多对多之间的关系 系列和活动。我知道这是 因为它是'可选的' 关系,但我还是有点 混淆为什么这会让它更多 柔性的。
实际上,我感到困惑!我最近一直在使用混合形式的继承,这是有道理的,因为需要构建事物的方式并最大限度地使用引用完整性。您可以轻松地执行以下操作(根据您所说的更符合模型的要求):
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)
尽管如此,使用mm允许您将特定数据添加到refClass
或使用多个引用类以获得基本相同的关系(这是我在某些情况下以这种方式执行此操作的方便之处)。所以在技术上它更灵活,但诚然,如果你说的是你唯一的要求,你将永远不需要这种灵活性: - )
此外,这是一个事实 那种多对多的关系 需要额外的SeriesEvent refClass要定义?
是
要从中继续发展,是吗? 必须定义 每当a。这个额外的连接 多对多发生?
无论何时调用集合的访问者,任何教条都不会自动处理。但是,在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();
}
我根本不会将系列和场地联系起来,因为这种关系总是取决于事件,因此不需要相关性。您可以将自己的自定义访问器/ mutators / finders添加到类中,以查询三级关系或从正确的相关对象中提取它。另外因为Event和Series之间的关系是可选的,所以我会使用多对多,因为它允许最大的灵活性。
如下所示:
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