0

我有一个存储points在表格中的 Web 应用程序,表格中的总分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 查询。

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

4

3 回答 3

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 小提琴演示

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

于 2012-12-13T06:01:06.493 回答
2

执行此操作的更有效方法如下:

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>where SELECT STATEMENTis the previous select 语句。

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

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

于 2012-12-13T05:43:41.500 回答
0

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

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

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

于 2012-12-13T05:46:01.783 回答