我正在創建一個網站,其中所有用戶都有一個每天更新的分數。我可以很容易地從這個分數創建排名,但是我希望能夠創建一週或一個月的「熱門」列表等。用於存儲用戶分數的Mysql數據庫設計
我的暴力設計將每天爲每個用戶,計算他們的分數並將其放入「分數」表中。所以每天的比分表會因有多少用戶而增加。我可以根據他們的分數變化在任何時間段內對用戶進行排名。
雖然我相信這在技術上會起作用,但我覺得必須有更復雜的方法來做到這一點,對吧?或不?我感覺像一個分數表,每天增加有多少用戶不能像其他網站那樣做。
我正在創建一個網站,其中所有用戶都有一個每天更新的分數。我可以很容易地從這個分數創建排名,但是我希望能夠創建一週或一個月的「熱門」列表等。用於存儲用戶分數的Mysql數據庫設計
我的暴力設計將每天爲每個用戶,計算他們的分數並將其放入「分數」表中。所以每天的比分表會因有多少用戶而增加。我可以根據他們的分數變化在任何時間段內對用戶進行排名。
雖然我相信這在技術上會起作用,但我覺得必須有更復雜的方法來做到這一點,對吧?或不?我感覺像一個分數表,每天增加有多少用戶不能像其他網站那樣做。
您可以通過不存儲比分上的所有快照都得到了最大的靈活性。相反,當它們發生時,記錄增量分數。
如果你有這樣的表:
用戶
SCORE_LOG
現在你可以累積分數用戶爲任何通過一個簡單的查詢,如:
select sum(scored_points)
from SCORE_LOG
where user_id = @UserID
and date_time <= @PointInTime
你也可以很容易地得到世界排名第一得分手一段時間的東西,如:
select
user_id
, sum(scored_points)
from SCORE_LOG
group by
user_id
where date_time >= @StartOfPeriod
and date_time <= @EndOfPeriod
order by
sum(scored_points) desc
limit 5
如果你到了生產和發現,你遇到的性能在實際發出,那麼你可以考慮對任何統計數據有意義的快照進行非規範化。這些快照統計數據的問題是它們可能與源數據不同步,因此您需要定期重新計算快照的策略。
Barranka與他的評論是在正確的軌道上,你需要確保你沒有複製任何可能的數據。
但是,如果您希望能夠恢復到某些老用戶的分數,或者可能能夠挑選出某一天,並在某個時間點查看誰是最高級的,即動態報告,那麼您需要記錄每個在日期旁分開記錄。爲此可以使用單獨的表格,因爲您可以通過SQL從現有用戶數據中推斷每日分數,並隨時將其輸入到表格中。
您的決定是有多少用戶記錄您要在歷史記錄中保留多久。我已經寫了下面這個想法,即「熱門名單」將成爲前5名用戶,您可以每天/每月運行CRON作業或計劃任務來運行插入,並清除舊數據。
用戶
score_ranking
所以要產生一個單一的數據排名,你可以插入此表。喜歡的東西:
INSERT INTO
`score_ranking` (`user_id`, `score_at_the_time`, `date_of_ranking`)
SELECT
`id`, `score`, CURDATE()
FROM
`users`
ORDER BY
`score` DESC
LIMIT
5
要閱讀某一特定日期(或日期範圍)的數據,那麼你可以這樣做:
SELECT * FROM score_ranking
WHERE date_of_ranking = 'somedate'
ORDER BY score_at_the_time DESC
一個字:** normalize **。您的數據庫設計必須正確標準化才能正常工作。問問你自己:爲什麼每次登錄每個用戶時都需要存儲用戶數據?如果僅存儲一次用戶數據並且僅將每個用戶的分數與用戶標識一起存儲,那麼這樣做會不會更好?不太容易出錯,你不覺得嗎? – Barranka
我不完全確定你的意思,他們的分數會每天更新,所以我怎麼只存儲一次? – maplater
那些不在線但玩過某些遊戲的用戶呢?你想把歷史記錄作爲記錄嗎?數字方面,目標在線用戶羣是什麼? – SparKot