将操作记录到数据库 - 架构和建议 - MySQL

时间:2011-08-24 19:06:15

标签: mysql database logging schema database-schema

我正在考虑将所有网站/用户操作记录到数据库中,并希望得到一些有关此内容的输入。此日志将用于各种事情,包括限制(登录尝试等),客户服务,一般维护等。

这样好吗?我想这取决于流量,但这会导致连续插入问题吗? (我正在考虑将InnoDB用于FK约束)

如果没有,您会建议什么样的架构,以便它足够灵活,以支持注册用户和匿名用户的不同类型的操作?

我想的是:

CREATE TABLE `logs` (
 `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
 `action` varchar(128) COLLATE utf8_bin NOT NULL,
 `user_id` bigint(20) unsigned DEFAULT NULL,
 `value` varchar(128) COLLATE utf8_bin DEFAULT NULL,
 `ip` varchar(40) COLLATE utf8_bin NOT NULL,
 `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
 PRIMARY KEY (`id`),
 KEY `action` (`action`,`user_id`),
 CONSTRAINT `logs_ibfk_1` FOREIGN KEY (`action`) REFERENCES `logs_actions` (`name`) ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin

CREATE TABLE `logs_actions` (
 `id` int(5) NOT NULL AUTO_INCREMENT,
 `name` varchar(128) COLLATE utf8_bin NOT NULL,
 PRIMARY KEY (`id`),
 UNIQUE KEY `name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin

这会是一个好方法吗?

4 个答案:

答案 0 :(得分:2)

user_id bigint(20),什么!你是Facebook的开发者吗? ;-)不会4字节int足够吗? See MySql Numeric Types

我将AUTO_INCREMENT放在logs_actions上,因为您需要将应用程序编码为特定值,您需要在插入时控制此值。

另外,如果你想减少一点开销,可以考虑放弃FK(至少是级联)。

答案 1 :(得分:1)

  • 使用MyISAM表进行日志记录,它们启用并发SELECT& INSERT查询 - 表级锁定不会干扰这些类型的查询。
  • 在MySQL中,UTF-8列每个字符需要3个字节,因此一个能够容纳128个UTF-8字符的列实际上能够存储128 * 3 = 384个字节,大于256个字节,因此这些列将有2个字节来计算列中的字符数,而不是1个字节(这可能是您所期望的)。
  • INT列使用ip列类型 - 可以节省大量存储空间,并且可以显着缩短检索时间。
  • 尝试批处理文本列action& value到一个列(可能名为queryString,代表页面中用户的操作和值)
  • 拥有此列顺序的索引:

    KEY `action` (`action`,`user_id`)
    

    错误,应该避免,因为文本列首先出现。

  • 我建议学习如何优化架构&用这本好书来查询MySQL:

      

    高性能MySQL:优化,备份,复制和   更多,第二版,作者:Baron Schwartz等。版权所有2008 O'Reilly   Media,Inc.,9780596101718。

  •   

答案 2 :(得分:0)

我认为MyIsam或Archive表更适合日志记录。因为您不需要事务或并发访问表。如果不打算从表中删除数据MyIsam将允许您进行并发插入,这样就可以避免阻塞整个表。

使用外键会减慢插入到表中的速度,所以如果您决定使用innodb,请尽量避免使用。

关于表格方案:

用于存储ip你应该选择int类型并使用inet_aton函数。见http://dev.mysql.com/doc/refman/5.0/en/miscellaneous-functions.html#function_inet-aton

答案 3 :(得分:0)

还要考虑以下事项:

The TIMESTAMP data type is used for values that contain both date and time parts.
TIMESTAMP has a range of '1970-01-01 00:00:01' UTC to '2038-01-19 03:14:07' UTC.

摘自:

http://dev.mysql.com/doc/refman/5.0/en/datetime.html

修改:

http://2038bug.com/

可能需要使用DATETIME。

问候。