mysql - 保存平均值与每次请求时计算平均值

标签 mysql concurrency playframework-2.0

我正在开发一个评级系统,这是我的问题。假设我的数据库中有这样的表:

places : id, name, description
place_marks : id, user_id, place_id, value, comment

当用户对地点进行研究时,我想向他发送按费率降序排序的地点列表。实现这一目标的最佳方法是什么?

解决方案1

  1. 获取名称对应的所有地点
  2. 计算每个地点的分数
  3. 创建新的有序列表

解决方案2

  1. 地点表格中添加标记
  2. 每次用户添加标记时,我都会计算标记
  3. 对于搜索,我只需正确查询数据库即可

在解决方案 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/

相关文章:

java - 每个线程都在单独的处理器上 - 这可能吗?

playframework-2.0 - 带有 Play 框架的 Browserify/CommonJS

php - UPDATE 查询更新之前设置的所有 TIMEDATE 列

mysql - 将 SQL Server 数据库架构移植到 MySQL 的最佳方式

php - 如何使用复选框(PHP)从 mysql 表中选择一行

c++ - 在其他线程中迭代该并发 vector 时调用 concurrency::concurrent_vector::push_back 是否是并发安全的?

mysql - 如何通过 Docker 在生产中处理数据备份

php - 在 PHP 中接受并发或并行请求

scala - Play 框架 2 的脚手架

java - Play Framework 2.0 中的动态模板