【发布时间】:2011-03-18 02:02:35
【问题描述】:
我正在寻找有关扩展积分排行榜系统的建议。我已经有了一个使用非常规范化策略的工作版本。第一个版本本质上是一个看起来像这样的表格。
UserPoints - PK: (UserId,Date) +------------+--------+----------+ |用户名 |积分 |日期 | +------------+--------+----------+ | 1 | 10 | 2011-03-17 07:16:36 | | 2 | 35 | 2011-03-17 08:09:26 | | 3 | 40 | 2011-03-17 08:05:36 | | 1 | 65 | 2011-03-17 09:01:37 | | 2 | 16 | 2011-03-17 10:12:35 | | 3 | 64 | 2011-03-17 12:51:33 | | 1 | 300 | 2011-03-17 12:19:21 | | 2 | 1200 | 2011-03-17 13:24:13 | | 3 | 510 | 2011-03-17 17:29:32 | +------------+--------+----------+然后我有一个存储过程,它基本上执行 GroupBy 用户 ID 并对点求和。我还可以传递@StartDate 和@EndDate 参数来创建特定时间段的排行榜。例如,顶级用户的天/周/月/生命周期的时间窗口。
这似乎适用于中等数量的数据,但随着点记录的数量超过一百万左右,事情变得明显变慢。我正在使用的测试数据是由大约 500 名用户在 3 个月的时间跨度内创建的超过一百万个点记录。
有没有不同的方法来解决这个问题?我已经尝试通过将点预先分组到小时日期时间存储桶中来对数据进行非规范化,以减少行数。但我开始认为我需要担心的真正问题是需要在排行榜中考虑的用户数量不断增加。时间窗口大小通常会很小,但越来越多的用户将开始在任何给定窗口内生成点。
很遗憾,我无法访问“作业”,因为我使用的是 SQL Azure 并且代理不可用(还)。但是,如果您有足够的说服力,我对使用不同的存储系统进行扩展的想法持开放态度。
我过去的工作经验告诉我应该研究数据仓库,因为这几乎是一个报告问题。但同时我需要它尽可能实时。
更新
最终,我希望支持每周一上午 8 点到周五下午 6 点的自定义排行榜。但这是在路上,为什么我尽量不要太看中聚合。我现在愿意接受基本的日/周/月/年/所有时间窗口。
棘手的部分是我真的不能将它们非规范化存储,因为我需要这些窗口是 TimeZone 可转换的。该系统是多租户的,因此所有数据都存储为 UTC。问题是对于不同的客户,一周从不同的时间开始。将总和汇总在一起会导致某些点落入错误的存储桶中。
【问题讨论】:
标签: sql database database-design azure azure-sql-database