2012-03-12 66 views
0

我正在做一個基於回合的遊戲,並嘗試構建匹配功能,當玩家選擇與隨機對手玩。我是一個noob當涉及到MySQL,所以我需要一些幫助。你將如何構建這個php-mysql查詢?

我在想這樣做:

  1. 當玩家選擇對戰隨機對手,勾選「waiting_list」表,看看是否有任何的對手那裏。

  2. 如果沒有任何對手,玩家加入到等待名單。

  3. 它有在輪候名單上的對手,從列表中刪除玩家,並與其它玩家開始遊戲。

我擔心的是,如果我這樣做,等待名單上的同一名球員是否有機會被幾名球員選中。想象一下,如果有100,000名玩家選擇自動匹配功能,數據庫(phpmyadmin)能夠處理它嗎?你將如何構建邏輯?

感謝

+0

您可以使用時間戳列(考慮到有自動匹配功能而不是選擇)以相同的順序分配玩家..也只是一個觀察:phpmyadmin只是用來管理數據庫的工具,而不是驅動程序;我認爲你使用mysql – mishu 2012-03-12 12:11:17

回答

1

爲了防止單個玩家被拉入多個遊戲,您可以在等待列表中添加一列(如果尚未存在)「GameIDAssigned」,默認爲0(甚至是PlayAgainstPerson)。

在查詢可供並顯示給衆多玩家的數據時,該記錄可能都具有類似的時間戳,但你只想要1。因此,挑選一個在一些隨機的方法,然後分配ID它等於時間戳和沒有分配的遊戲。如果它回來,1記錄被更新,它是你的。如果它被分配給其他人,則GameIDAssigned已被填充,從而阻止您再次分配它。如...

PersonIDFromWaitingList = SomeValueEvenIfBySQLSubSelect 

Update YourWaitingListTable 
    set GameIDAssigned = SomeCurrentGameIDSequence 
    where DateTimeStampColumn = ValueWhenOriginallyQueried 
    AND GameIDAssigned = 0 

沒有看到的你的遊戲是如何構成的任何其他元素或列的表中,沒有更多的,我可以在這個時候提供,但希望足以讓你明白我的意思。如果一個等待名單的人被試圖同時被多人分配,則只有第一個獲得更新完成的人(而gameIDAssigned仍然= 0)獲勝,並且所有其他嘗試獲取該人的人都會錯過並需要嘗試下一個可用...

+0

AFAIK取決於MySQL存儲引擎,這是不安全的。 – hakre 2012-03-12 13:47:18

+0

@afaik,不要諷刺,但它怎麼不安全...... – DRapp 2012-03-12 13:54:26

+0

同一行的多個修訂版。併發讀取可以獲得前一個。 – hakre 2012-03-12 14:16:11

3

我擔心的是,如果我像這樣做,有沒有可能在等待名單上的同一個玩家,將幾名球員作爲選。

什麼你與你點1)描述爲3),是所謂的業務交易,你有一個原子此操作可以由一個玩家一次只能執行。

因此,應該封裝操作成一個對象,處理它,所以你有一個接口在您的業務邏輯來執行該交易。

然後你需要實現交易。事務可以成功或失敗,您可以使用返回值或異常來處理失敗。

交易本身必須確保您的擔心被刪除。這可以在MySQL中通過專門鎖定匹配表來完成,進行匹配,刪除或添加玩家/對手到等待列表並釋放鎖。

請參閱12.3.5. LOCK TABLES and UNLOCK TABLES Syntax­Docs

表鎖會影響性能,因爲只要一個表被鎖定,沒有其他會話可以訪問它(等到鎖被釋放)。

因此,鎖定時間短是明智的。如果交易需要10毫秒就可以併發活動事務的數量乘以它讓你的表現時表示:

0.010 seconds * 100 000 transactions = ~ 16.7 minutes 

請注意,這不是可能是你有10萬個併發事務,因爲不是所有的玩家匹配一次。但是,您需要跟蹤數字,因爲系統可能會在一段時間後停止。