这是活动日志的实用概念吗?

时间:2012-06-01 01:28:15

标签: php mysql

我想使用一个InnoDB MySQL表为我的PHP站点创建一个“活动日志”。访问该网站的任何人都会在表格中插入一条新记录,该记录将记录......

  • 他们的IP地址
  • 他们登录的帐户的ID(如果没有登录则为null)
  • 他们向服务器发出的请求
  • 收到请求的日期和时间
  • 发送了用户代理,但仅当 PHP脚本确定它是机器人时(否则为空)

同时,我可以使用该表来...

  • 确定每页每月/每月/每天等的点击量
  • 确定每年/每月/每天/等的唯一身份访问者数量
  • 如果可行,使用PHP脚本即时检索以前的信息,如果我想
  • 过滤掉机器人请求

对于下面的表格,我有一些问题(以及一些推理):

CREATE TABLE `activity` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `ip` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
  `account` int(11) unsigned DEFAULT NULL,
  `request` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
  `time` time NOT NULL,
  `year` year(4) NOT NULL,
  `month` tinyint(2) unsigned NOT NULL,
  `day` tinyint(2) unsigned NOT NULL,
  `bot` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  PRIMARY KEY (`id`)
)
  1. 这种日志记录是否实用?实际意义插入和选择可以在几毫秒内完成。我意识到很多的记录可以通过这种方式生成,但我不完全确定是否有更好的方法来完成我想做的一切。

  2. 此外,选择“今天”的点击次数并将其放在每个服务页面的底部是否可行?我对使用大型数据库相对较新,而且我仍在学习哪些查询会很快,哪些查询会很痛苦。

  3. 我应该保留主键吗?我可以用它来回去并随心所欲地编辑我想要的任何行(由于一个重要的原因,我真的看不到自己在做什么),但是它会显着减慢我的INSERT吗?有什么好处吗?同样,我不应该出于同样的原因添加任何指数 - 对吧?包括外键(对于帐户列)?

  4. 我可以选择捕捉当前的日期和时间吗?我首先使用单个DATETIME列启动此表,但在某处读取这样的表可能会从分割日期信息的列中受益;例如,如果我想计算“今天”的点击次数,我可以将结果限制为......

    WHERE year="2012" AND month="02" AND day="16"
    

    ......与......相反。

    WHERE date > "2012-02-15 23:59:59"
    
  5. 提前致谢!

2 个答案:

答案 0 :(得分:2)

到目前为止,您的日志表似乎合理。但是,而不是列timeyearmonthday我肯定会使用TIMESTAMP,这只是四个字节。然后为此列添加索引。

如果您对范围搜索有疑问,则应获得良好的响应时间。

WHERE created >= "2011-01-01 00:00:00"
    AND created < "2012-01-01 00:00:00"

答案 1 :(得分:1)

这种日志记录方式很实用,但您可以从使用分区(和子分区)中受益:http://dev.mysql.com/doc/refman/5.1/en/partitioning.html

由于您正在存储活动日志,因此随着时间的推移,您可能会拥有非常大的数据集。分区可能特别有用,因为您需要查看特定的月份和年份。

例如,如果日期列的数据类型是DATE或DATETIME,您可以执行以下操作:

PARTITION BY RANGE (MONTH(the_date))
(PARTITION p0 VALUES LESS THAN (0),
 PARTITION p1 VALUES LESS THAN (1),
 PARTITION p2 VALUES LESS THAN (2),
...[and so on up to 12]);

这将为您提供每月数据的分区。使用不同的分区进行测试后,尝试使用“explain partitions select * from ...”运行查询,您将能够看到查询的执行方式以及扫描的分区。分区的最佳方法可能需要围绕最常见的查询进行定制。例如,您主要查看过去30天的数据吗?每月快照?自定义日期范围?这些都可能对分区的结构产生影响。

更进一步,你可以在每个分区中有子分区。为此,可以使用散列分区:http://dev.mysql.com/doc/refman/5.1/en/partitioning-hash.html

您的主要关键问题也会受到分区的影响。表中的主键(以及任何唯一键)必须使用分区中使用的每一列。