2010-09-11 85 views
2

我正計劃一個關係數據庫來存儲撲克遊戲數據(比如手中的歷史數據)。我想幫助搞清楚如何設計關聯。似乎應該有4個模型:遊戲,手牌,玩家和動作(給定玩家的單個動作,如提升,摺疊,呼叫)。讓我列出我有什麼:德州撲克數據的關係數據庫結構

class Game < ActiveRecord::Base 
    has_many :hands 
    has_many :actions 
    has_and_belongs_to_many :players 
end 

class Hand < ActiveRecord::Base 
    has_many :actions 
    belongs_to :game 
    has_and_belongs_to_many :players 
end 

class Action < ActiveRecord::Base 
    belongs_to :game 
    belongs_to :hand 
    belongs_to :player 
end 

class Player < ActiveRecord::Base 
    has_and_belongs_to_many :games 
    has_and_belongs_to_many :hands 
    has_many :actions 
end 

這是否有意義?

回答

1

如果你打算使用has_and_belongs_to_many,你或許應該切換到使用has_many ..., :through,因爲它更容易管理。你已經有一個操作模式已經做了你需要的東西,而無需創建一些連接表:

class Game < ActiveRecord::Base 
    has_many :hands 
end 

class Hand < ActiveRecord::Base 
    has_many :actions 
    belongs_to :game 

    has_many :players, 
    :through => :actions, 
    :source => :player 
end 

class Action < ActiveRecord::Base 
    belongs_to :game 
    belongs_to :hand 
    belongs_to :player 
end 

class Player < ActiveRecord::Base 
    has_many :actions 
    has_many :played_games, 
    :through => :actions, 
    :as => :game 
    has_many :played_hands, 
    :through => :actions, 
    :as => :hand 
end 

一般情況下,你已經參與了您的查詢更少的表,速度越快,他們將運行。涉及任何種類的JOIN都將導致不可預知的查詢性能。

請務必仔細爲表格編制索引,並使用EXAMINE聲明確保在使用索引時達到索引。如果您將這些數據加載到數百萬條記錄中,那麼表掃描將會非常痛苦,而且這樣的遊戲並不需要很長時間,因爲單手涉及數十個動作,並且通常每小時玩數十隻手。

+0

嗨Tadman,謝謝你的幫助 - 這非常有用。我明白你是如何設置Game,Hand和Action模型的,但我對Player模型還是有點不清楚。你能解釋一下Player表的外觀(即包含哪些外鍵)?是否有一個帶有hand_id值的播放列?另外,你會介意解釋爲什麼遊戲只與手相關嗎?再次感謝您的幫助! – rymodi 2010-09-11 21:24:04

+0

如果您按照鏈接,例如'game.hands.first.players'或創建自己的自定義查詢以更有效地加入,則可以從遊戲導航到玩家。另外,'has_many ...,:through'關係不涉及新列,它將通過利用現有關係來工作。在你給出的例子中,「玩家」表只需要一個「id」列來工作,其餘的由你決定。行動就是定義所有關係的地方。 – tadman 2010-09-11 21:30:55

1

作爲初稿是有意義的。從你所給出如下表和鍵所產生的關聯:

Game  :: Game_id (PK);.... 
Hand  :: Hand_id (PK); Game_id (FK);.... 
Player  :: Player_id (PK); Action_id (FK); 
ActionType :: ActionType_id (PK); Type; 
(Note this table will only have three records - raise, fold, call) 
Action  :: Action_id (PK); ActionType_id (FK); Game_id (FK); Hand_id (FK); Player_id (FK);.... 
PlayerHand :: Player_id (FK); Hand_id (FK); Has_or_Belongs; (PK is (Player_id, Hand_id)) 
GamePlayer :: Game_id (FK); Player_id (FK); Has_or_Belongs; (PK is (Game_id, Player_id)) 
+1

使用整數或枚舉來分類ActionType會更好。 – theodorton 2012-05-10 00:10:57