我有一个将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)
用户表中的值可能与points表中的总和不同步,我希望能够偶尔为每个用户重新计算所有点的SUM(例如,每月一次)。我可以编写一个PHP脚本,它可以遍历用户表中的每个用户,找到该用户的总和并更新total_points,但这将是很多SQL查询。
有没有更好(有效)的方式来做我想做的事情? 感谢...
答案 0 :(得分:2)
更有效的方法是:
User Table
user_id
Points Table
id | date | user_id | points
Total Points View
user_id | total_points
视图实际上是伪装成表的select语句。 select语句为: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以来已经有一段时间了,所以我不记得它的特质。
答案 1 :(得分: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;
请注意:正如@FireLizzard所述,如果第二个表中的这些记录经常更新或删除,则必须有其他AFTER UPDATE
和AFTER DELETE
个触发器同时,保持两个表同步。在这种情况下,在这种情况下@FireLizzard会更好的解决方案。
答案 2 :(得分:0)
如果你想每月一次,你就不能只处理MySQL。你在这里有太多«逻辑»代码,并且在数据库中放置太多逻辑并不是正确的方法。 Karan Punamiya的触发器可能很好,但是它会更新点表中每个插入的user_table,而这不是你想要的。
对于您希望能够删除点的事实,只需在点中添加bsarv新的否定行,不要删除任何行(它将破坏历史记录)。
如果你真的想定期,你可以运行一个cron脚本,甚至可以调用你的PHP脚本;)