我正在创建一个网站,其中所有用户都有一个每天更新的分数。我可以很容易地从这个分数创建排名,但是我希望能够创建一周或一个月的“热门”列表等。用于存储用户分数的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