1

我想使用一个 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"
    

提前致谢!

4

2 回答 2

2

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

如果您有范围搜索的查询,您应该获得良好的响应时间。

WHERE created >= "2011-01-01 00:00:00"
    AND created < "2012-01-01 00:00:00"
于 2012-06-01T01:42:05.680 回答
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

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

于 2012-06-01T04:05:45.763 回答