2009-11-04 169 views
2

我有2個數據庫表:團隊和遊戲。應該將多對多的數據關係視爲多對多關係嗎?

對於這個問題,我們正在處理足球(足球)隊和比賽。

每場比賽都有兩支球隊,一般是主隊和客隊,儘管偶爾兩隊都可以保持中立。

我的問題是我是否應該在Games表中使用2個外鍵(home_team_id,away_team_id)來表示這種數據關係,還是我應該使用與games_teams表的多對多關係來鏈接這兩個表,其中我還需要存儲球隊是主隊還是客隊,看起來有點矯枉過正。

爲了增加混淆,我使用KohanaPHP中的ORM庫,並且這些將期望fk被稱爲team_id或鏈接表只包含2列。如果你在KohanaPHP有這個問題的經驗,那麼請留下回復,否則任何一般建議也非常感謝。

+0

如果你不打算遠遠這個(遊戲在中立的地方等),保持簡單,我會說。 我曾經做過類似的事情,只是在遊戲桌上有兩個外鍵。 然而,我不能幫你的是KohanaPHP的東西,這就是爲什麼我不會發布這個答案;) – Franz 2009-11-04 16:05:36

+1

感謝您的想法傢伙,似乎每個人都同意使用2 fk的。指向Malphas,因爲他是第一個回答,並沒有很多(像我):) – Matt 2009-11-04 16:18:25

+2

只要確保評論WTF你這樣做下一個程序員不會出現,不知道這種關係如何工作 – 2009-11-04 16:22:11

回答

3

如果您希望能夠在您的數據庫服務器上固定「Xth Normal Form」徽章,那麼它應該被視爲多對多,否則,我認爲您會減少查詢開銷您只需要通過加入1個表,您希望獲得一些有用的數據。

+0

我不同意。兩張桌子的設計至少是BCNF,在這種情況下進一步無用。 – 2009-11-04 16:08:31

+0

意志提前12秒,也正確。解除歸一化可以成爲你的朋友。 – 2009-11-04 16:09:10

8

只要使用兩列,否則你只需要在joiner表中限定它。這不像是一個睡覺的定時炸彈,突然有一天,你會發現你需要有一個真正的多到很多。

+1

+1睡眠定時炸彈 – 2009-11-04 16:07:07

+0

也許這些規則會改變,以便6個團隊玩六角... – 2009-11-04 16:07:14

+4

雖然嚴重。威爾是對的。速度更快,而且特定的要求不會很快改變。 – 2009-11-04 16:08:03

5

2列在我看來是完全適合的。任何遊戲只能有兩個團隊的事實通過具有兩列來反映在數據庫模式中。通過引入鏈接表,您可以引入單個遊戲可能包含2個主隊和2個客隊的可能性,並且您需要額外的驗證以確保此場景從不發生。通過將事物分離到兩列,您的模式固有地強制數據完整性。

+0

這是不正確的。如果您指定兩列是唯一的。 – 2009-11-04 16:15:00

+0

對不起,我可能有點不清楚。我所說的是,鏈接表方法允許2個主隊(或者任何數目)的可能性,因此需要對其進行驗證。你說得對,列可以通過兩列方法變得獨一無二。 – 2009-11-04 16:24:19

2

就規範化而言:是的。只有一對多或多對多可以分解爲一個或多個一對多關係。

但現實地說,如果我要保存像GENDER這樣的東西。我真的需要一個多國和​​一個日期時間戳附加到此?

令人驚訝的答案是肯定的 - 但只有當我出於商業原因需要跟蹤性別變化時 - 對於大多數實際目的,答案是否定的。

我會保留一個表與兩個鍵 - 除非有商業原因跟蹤它。

1

根據你如何抽象它,我會說足球比賽必須有兩支球隊,在這種情況下,在比賽表中有列不僅更方便,更正確。

我甚至可以想象團隊ID是遊戲主鍵的自然部分。

1

完全認爲你不應該有一個單獨的表。程序員更容易,數據庫更容易。很好想想如果,但聽起來你已經有了。不要被認爲正常化總是爲所有事情走的路。

1

我尊重對方的回答,說使用兩列是最佳選擇,但是,您提到您在Kohana中使用ORM庫。通過在遊戲桌中使用兩列,您將失去ORM功能以實現多對多關係。如果你設置了一個games_teams透視表,你可以做到以下幾點:

$game = ORM::factory('game', 1); // 1 is the game id 

然後你可以遍歷在那場比賽的球隊:

foreach ($game->teams as $team) { 
// do stuff with $team 
}