计算用户参与/活动

时间:2009-10-13 22:29:50

标签: php mysql

我有一个网站,使用多个MySQL查询计算用户参与/活动。

对于典型用户,我会问:

他们做了多少次更新? 他们上传了多少张照片? 等等。

这些只是相关表格,更新,照片的基本COUNT查询。然后我将每个的COUNT值相加得到一个分数。每个查询需要一个JOIN,每个查询大约需要0.0006秒,每个用户共有10个查询,总共0.006秒。

虽然对于一个用户来说并不是那么糟糕,但我必须为100,000个用户计算,理论处理时间为10分钟,并且有大约1,000,000个数据库查询。感觉我正以错误的方式接近问题并且想知道是否有人有任何想法?

我曾考虑将用户分数存储在他们的用户记录中,并在每次执行特定操作时将其递增但是它不那么灵活(我不能回去查看某一天累积了多少积分实例)。

任何帮助都非常感谢!

5 个答案:

答案 0 :(得分:2)

拥有user_activity链接表。它需要action_iduser_idtimestamp。例如,当用户上传照片时,会创建一条记录activity_id = 2(对于activities表引用的“照片上传”),user_id和当前时间戳。这很容易查询,并且当您拥有数以万计的用户时,无需担心长时间运行的查询。

答案 1 :(得分:2)

假设您的表格在每个表格都有某个user_id字段的位置,您可以执行以下操作来获取用户完成的“活动”:

SELECT users.user_id, 
       (update_counts.update_count + photo_counts.photo_count) AS activity_count
FROM   users 
    INNER JOIN 
        (
        SELECT updates.user_id AS user_id, 
               COUNT(updates.*) AS update_count
        FROM   updates
        GROUP BY user_id
        ) AS update_counts ON users.user_id = update_counts.user_id
    INNER JOIN 
        (
        SELECT photos.user_id AS user_id, 
               COUNT(photos.*) AS photo_count
        FROM   photos
        GROUP BY user_id
        ) AS photo_counts ON users.user_id = photo_counts.user_id   
GROUP BY users.user_id 

显然你可以根据需要添加表格,你可以根据需要加权。如果你在每个表中的user_id字段上有一个索引,它应该表现得相当好,尽管它取决于你的表有多大。

一旦表格变得庞大,您将需要开始在缓存表中缓存activity_count。如果需要,您可以按日期缓存值。

如果您只需要粗略估计,您可以按常规频率运行此查询(例如,每晚一次)并缓存结果;这比为每个表编写触发器以更新缓存表更具侵入性。

答案 2 :(得分:0)

除非你想进行11路连接,否则我会为每个用户更新后插入的目的创建一个单独的表。

该表应该只包含用户名,时间戳,部分(来自其中的表)以及其他表中的唯一ID,因此您可以对删除等进行反向引用。

答案 3 :(得分:0)

听起来好像你在真正需要之前尝试进行优化。如果您没有100,000个用户,则在必要时无需担心此类问题。

据说没有理由不优化,只是不要试图为你不需要的解决方案来解决问题。

虽然您可能会遇到轻微的不一致,但您可以尝试在登录时缓存每个用户计数的结果(使用memcached),并在更新其中一个计数时仅更新缓存。如果用户非常活跃,那么每小时左右更新一次会更有效。

答案 4 :(得分:0)

这可能对您的应用程序来说太过分了,但您可以随时使用OLAP路由。这将允许您沿多个维度(例如用户和时间跨度)预先聚合度量。这为您提供了一个灵活的框架,可满足各种报告需求。 SQL Server Analysis Services包对我们公司运作良好。