【问题标题】:Recalculate values in MySQL tables重新计算 MySQL 表中的值
【发布时间】:2012-12-13 15:06:39
【问题描述】:

我有一个将points 存储在表格中的网络应用程序,user 表格中的总分如下:

User Table
user_id | total_points

Points Table
id | date | user_id | points

每次用户赚取积分时,都会发生以下步骤:

1. Enter points value to points table
2. Calculate SUM of the points for that user
3. Update the user table with the new SUM of points (total_points)

用户表中的值可能与积分表中的总和不同步,我希望能够不时地重新计算每个用户的所有积分的总和(例如,每月一次)。我可以编写一个 PHP 脚本,它可以遍历用户表中的每个用户并找到该用户的总和并更新 total_points,但这将是很多 SQL 查询。

有没有更好(有效)的方法来做我想做的事情? 谢谢...

【问题讨论】:

  • 插入触发器后不能使用mysql更新用户表吗?
  • 我没有 mysql 触发器,但在 php 代码中有一个函数,就像触发器一样。问题是,有时我从数据库的点表中手动删除行。我需要做出规定,从再次计算总和的网络应用程序中删除点,但现在为时已晚:P
  • 你用的是哪个版本的mysql? MySQL 触发器非常有用,而不是 PHP 代码。您可以在点表上创建插入、更新、删除触发器来更新用户表。它会比 PHP 代码好得多
  • 使用触发器可以同步两个表。

标签: php mysql


【解决方案1】:

更有效的方法如下:

User Table
user_id

Points Table
id | date | user_id | points

Total Points View
user_id | total_points

视图实际上是伪装成表的选择语句。选择语句将是:SELECT "user_id", SUM("points") AS "total_points" FROM "Points Table" GROUP BY "user_id"。要创建视图,请执行CREATE VIEW "Total Points View" AS <SELECT STATEMENT>,其中SELECT STATEMENT 是前面的选择语句。

创建视图后,您可以像对待任何常规表格一样对待它。

P.S.:除非您的表名实际上包含空格,否则我不知道引号是必需的,但是自从我使用 MySQL 以来已经有一段时间了,所以我不记得它的特质。

【讨论】:

  • 谢谢。我将使用什么 SQL 语句将 total_points 值从 total_points 视图复制到用户表?我可以在一个 SQL 查询中完成吗?
  • 我建议不要将其复制到用户表中。您可以修改 Select 语句以返回所需的任何和所有列。关系数据库的方式是将点和用户信息等数据存储在两个单独的表中,并且永远不会将它们放在同一个表中。也就是说,要在修改点表后立即更新,触发器是您的最佳选择。要定期更新,最好使用更新脚本和cron 作业。
  • 感谢您的建议。但这一次,我负担不起重组表格的费用。我只需要一次获取更新的值,因为我已经手动删除了一些点。我需要用正确的总分更新用户表。
【解决方案2】:

您必须为此使用触发器,以使用户的总点数与user_points 表同步。比如:

Create Trigger UpdateUserTotalPoints AFTER INSERT ON points
FOR EACH ROW Begin
    UPDATE users u
    INNER JOIN 
    (
       SELECT user_id, SUM(points) totalPoints
       FROM points
      GROUP BY user_id
    ) p ON u.user_id = p.user_id
   SET u.total_points = p.totalPoints;
END;

SQL Fiddle Demo

注意:正如@FireLizzard 所指出的,如果第二个表中的这些记录经常更新或删除,您还必须有其他AFTER UPDATEAFTER DELETE 触发器,以保持两个表同步。在这种情况下,@FireLizzard 的解决方案在这种情况下会更好。

【讨论】:

  • 您还可以为after deleteafter update 创建触发器
  • @FireLizzard - 好点。是的,要保持表同步,必须有 after deleteafter update,但只有在更新第二个表时才需要。
【解决方案3】:

如果你想要每月一次,你不能只处理 MySQL。您在这里有太多“逻辑”代码,并且在数据库中放入太多逻辑不是正确的方法。 Karan Punamiya 的触发器可能很好,但它会在 points 表中的每次插入时更新 user_table,这不是您想要的。

对于您希望能够删除点的事实,只需在点中添加 bsarv 新的否定行,不要删除任何行(它会破坏历史记录)。

如果您真的需要定期执行此操作,您可以运行一个 cron 脚本来执行此操作,甚至调用您的 PHP 脚本;)

【讨论】:

    猜你喜欢
    • 2018-11-15
    • 2015-07-12
    • 2020-07-24
    • 2012-09-13
    • 1970-01-01
    • 2021-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多