PHP的建议和;用于Web应用程序的MySQL统计报告

时间:2010-10-20 01:42:51

标签: php mysql statistics

背景

我在我的小公司'继承'了一个php webapp 经过多年的唠叨终于得到了 去掉意大利面条代码然后重新开始。

我们希望记录系统中的每个操作,例如:

  • 用户X查看了项目Y
  • 用户X更新了项目Y
  • 城市Z上的新项目Y

以后提供不同分辨率(日,月,年)的图表 在系统中完成的操作。

在之前的版本中,我们有一张表,其中有20,000,000条记录 2005年,这将让您了解我们已经拥有的大量数据 有,这只是众多统计数据之一。

实际问题:

您建立近实时的建议 系统来创建这个统计数据?

备注:

  1. 图形已经通过谷歌的可视化API
  2. 涵盖
  3. 我不习惯使用任何NoSql数据库或 消息服务器,crons或其他任何东西 完成的工作,但更喜欢mysql / php 解决方案
  4. 我目前的思路是 自动为每个创建一个表 统计我要保存,并创建 几个聚合表(按月,按天,按年) 缓存结果。
  5. 我知道这是一个广泛的问题,但欢迎任何建议

3 个答案:

答案 0 :(得分:2)

如果所有用户都必须注册,我会使用完整的规范化解决方案。

USERS TABLE            OBJECTS TABLE
---------------        -----------------     
user_id (primary)      object_id (primary)


USERS_TO_OBJECTS TABLE
--------------------
user_id (index)
object_id (index)
time (index)
action (index)
? object_type (index) // could be useful to speed things up

这种设置可能会在制图时为您提供最大的灵活性,并且也会非常快,因为如果您不需要它们,可以省略用户或对象。

修改

假设城市X(id 9876)由用户123(id 1234)更新......

1234    - user_id (the user that did the action)
9876    - object_id (the object where the action was done)
xyz     - time
updated - action type (so that you select only specific actions)
city    - object type (so that you select only specific objects)

我已经用40M行填充了这个表,结果非常可接受。

对于上一周的UPDATED城市数量的简单COUNT,为0.002秒。随机插入数据。

修改2

如果你发现自己有一个非常庞大的表,你可以使用MySQL分区,你的架构是完美的。我真的不知道你将如何使用这些表,但你可以:

按范围划分。在日期上组织分区。每个新的一个月左右你都会有一个新的分区。

按键分区。按操作组织分区。每个动作都适用于它的正确分区。

您可以将more on partitions on MySQL's sitethis article gives you some detail签入微调分区。

答案 1 :(得分:1)

你可以考虑像Redis这样的“数据库”。 Redis使用链接列表来存储列表类型,因此您可以轻松地将LPUSH添加到如下列表中:

$action = array(
    "type"=>"page_view",
    "url"=>"/example/path",
    "user"=>"user1",
    "timestamp"=>$_SERVER["REQUEST_TIME"]
);
$r = new Redis();
// Redis connection info //
$r->lPush("global_history", json_encode($action));

LPUSH操作在O(1)运行,因此不应成为问题。检索结果可能有点棘手(列表的O(n)时间)。 Redis也主要基于内存(虽然开发版包括“虚拟内存”支持),所以它很快,但你可以很容易地用完房间。

我使用此技术记录我运行的音乐网站的历史记录和统计信息。它非常成功,只需很少的努力即可提供非常快速的结果。

如果您想让它更加稳固,您可以使用Hadoop或其他技术从列表末尾(RPOP)提取并将结果归档为更永久的格式(例如,XML推送到Amazon S3)。然后,您可以在查看旧数据时使用Google可视化文件从存档中查找数据(这将是静态的,已编译的数据),而在Redis前端查找更新的数据。

希望这有帮助!

答案 2 :(得分:0)

我很高兴你终于得到了重新设计该项目的绿灯。可能在这里回复太迟了,但MongoDB(带有Capped Collections功能)的实现可以更好地完成这种工作。实现它并不太费时,所以也许还有机会。

无论如何,希望一切顺利。