如果你願意存儲更多的數據,我會建議這種設計。
而是扣除每次(在遊戲中的「狀態」強烈依賴),而是存儲在玩家們的每一個動作的要點。當然,讓我們這個表:
id | playerid | action | stamp
----+----------+----------+------------------------
1 | 1 | e2 to e4 | 2011-10-27 04:00:00-04
2 | 1 | | 2011-10-27 04:30:00-04
3 | 1 | | 2011-10-27 06:00:00-04
4 | 1 | | 2011-10-27 07:45:00-04
5 | 1 | | 2011-10-27 08:00:00-04
等等,等等
E2至E4是順便說一下,常見的開局之一的一步棋。你的遊戲,我無法真正設計。然而,「行動」是可選的,你只需要存儲事件發生的行爲來計算懲罰。 (但是,當然,只要你有空間這樣做,就可以存儲額外的信息)。
在這種情況下,「id」是代理鍵。在PostgreSQL中,DDL看起來像:
CREATE TABLE actions(
id BIGSERIAL PRIMARY KEY,
playerid int,
action text,
stamp timestamptz,
UNIQUE(playerid, stamp));
元組(playerid,蓋章)將是 「真正」 的主鍵。 「id」是代理鍵。
要查看時間戳的差異,使用窗口函數的代碼相對簡單。 (繼續使用PostgreSQL)
select playerid, time_between, id FROM
(SELECT playerid,
stamp - lag(stamp) OVER() as time_between,
id FROM actions
ORDER BY stamp)
as ss
WHERE playerid = 1
AND time_between > '1 hour';
樣本輸出,給早期的測試數據:
playerid | time_between | id
----------+--------------+----
1 | 01:30:00 | 3
1 | 01:45:00 | 4
你不都有cron作業。你存儲了更多的數據(所以它更容易「撤銷」動作)。如果玩家願意,你可以回顧過去的動作。如果計算懲罰變得效率低下,那麼您總是可以將分數緩存在更高的級別。
窗口函數在MySQL btw中不可用。但是可以在PostgreSQL,SQL Server和Oracle中使用。
編輯:如果空間是一個問題,那麼你可以隨時「垃圾收集」這張桌子定期。不過,那會是很多遊戲。每行佔用約48個字節(假設爲空「行動」)。如果你有1000個玩家,每個玩家用40個動作玩200場比賽,你只有384MB的數據。
您是否將此數據存儲在某種關係數據庫中? –
是的。這還沒有實現,但在我目前的設計中,我正在考慮使用sql數據庫來實現狀態永久性。 –
您可能想要考慮在單個查詢中更新點的方法,而不必爲單個方法調用實例化潛在的大量對象。 –