我正在开发一个评级系统,这是我的问题。假设我的数据库中有这样的表:
places : id, name, description
place_marks : id, user_id, place_id, value, comment
当用户对地点进行研究时,我想向他发送按费率降序排序的地点列表。实现这一目标的最佳方法是什么?
解决方案1
- 获取名称对应的所有地点
- 计算每个地点的分数
- 创建新的有序列表
解决方案2
- 在地点表格中添加标记列
- 每次用户添加标记时,我都会计算标记
- 对于搜索,我只需正确查询数据库即可
在解决方案 1 中,问题可能是性能问题(即使我在查询中计算标记),而在解决方案 2 中,如何确保在计算标记时避免冲突?
我正在使用 Play2 和 MySQL。 感谢您的帮助。
最佳答案
您担心解决方案 2 中会出现什么样的冲突?我假设您指的是您正在计算标记的可能性,同时提供了一个新标记,并且您再次开始相同的计算,其中第二个计算存储在第一个计算之前。换句话说,您没有最新的平均值。
在给出答案之前,我认为你应该让你的代码以最简单的方式工作。只有当你遇到问题时我才会考虑优化。在您真正从任何优化中受益之前,您将需要相当多的标记和访问者(假设是 Web 界面)。我的建议是稍后优化。
对于这个答案,我会考虑 3 个选项。我不知道 Play2,所以我的答案保持通用。
1) 不关心:这种情况发生的变化相当有限,并且只有在流量非常高时才会出现问题。由于您只是计算临时值(直到出现新标记),因此我会忽略这种可能性。下次有人提供分数时,您的统计数据将是正确的。 1a) 您可以每晚重新计算平均值,以确保第二天的平均值是正确的。
2) 确保计算同步。换句话说,确保永远不会同时开始 2 个计算。有多种选择,因为我不知道 Play2,所以我会引用提供更多信息。
3) 这是最好的方法。由于您预计会有高流量,因此您希望确保能够为客户提供服务。你想要的最后一件事是例如花费 50% 的 CPU 能力来进行计算。一种选择是让一个单独的进程在后台运行,偶尔检查标记表。一旦检测到新标记,它将计算平均值。由于您只有 1 个进程,因此您可以限制其占用的 CPU 时间以及数据库上的负载。在高负载期间,您的计算可能会有点落后,但一旦负载较低,计算速度就会加快。
如果您确实遇到交通拥堵,请选择选项 3)。根据您的问题,我建议对您的产品采取选项 1),调查选项 2 以了解更多信息,例如信号量并将选项 3) 视为学习练习。
祝你好运。
关于mysql - 保存平均值与每次请求时计算平均值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17900491/