2010-11-29 117 views
0

我正在爲在Doctrine中工作的項目設計一個模型進行試驗,並且我想了解如何定義不同關係的一些建議。在Doctrine中定義關係

我有3個表

地點,系列和事件

  • 地點有很多活動,並且可以承載的是有時但不一定是系列的一部分事件。
  • 系列是一系列的活動,可以在同一場地或不同的場地進行。
  • 事件總是發生在場地,可以選擇作爲系列的一部分。

我的理解是,場館和系列賽將是一個多對多的關係,因爲許多場館可以有很多系列賽事,反之亦然。這種關係是否是「可選」的事實會改變事物嗎?

我也明白,事件會與場館和系列賽成爲一對多的關係,因爲一個場館可以有很多活動,一個系列可以有很多活動,但一個活動只能有一個。

我看着這個正確的方法,任何人都可以建議在Doctrine中定義這個最好的方法嗎?

回答

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) 

不過雖然用毫米允許您將特定的數據添加到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和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