如何通过MySQL触发器操作对数据更改进行分组

时间:2010-02-08 10:51:50

标签: mysql logging triggers

我在MySQL中使用触发器来记录对数据的更改。这些更改记录在行级别上。我现在可以在我的日志表中为每个更改的行插入一个条目。但是,我还需要记录更改所属的操作。

例如,像“DELETE * FROM table WHERE type = x”这样的删除操作可以删除多行。使用触发器,我可以将每个已删除行的条目插入到日志表中,但我还想为整个操作提供唯一标识符,以便日志表看起来像:

log_id  operation_id  tablename  fieldname  oldvalue  newvalue

1       1             table      id         1         null  
2       1             table      type       a         null
3       1             table      id         2         null
4       1             table      type       a         null
5       2             table      id         3         null  
6       2             table      type       b         null
7       2             table      id         4         null
8       2             table      type       b         null

在MySQL中是否有办法识别行更改所属的更高级别操作?或者这只能通过应用程序级代码实现?在将来,能够记录操作所属的事务也是很好的。

另一个问题是,除了使用查询日志之外,是否可以捕获实际的SQL查询。我自己也不这么认为,但也许我错过了一些东西。当然可以在应用程序级别捕获这些内容,但目标是尽可能减少对应用程序级代码的入侵。

如果MySQL无法做到这一点,那对于其他数据库系统又如何呢?对于当前的项目,不能选择使用MySQL之外的其他东西,但了解未来的项目会很好。

修改 在伪代码中,我想实现以下类型的触发器:

CREATE TRIGGER tablename_log_insert
AFTER INSERT ON tablename
INSERT INTO log_operations (operation_type, relation) VALUES ('insert', 'tablename');
SET @operation_id = LAST_INSERT_ID();
FOR EACH ROW
BEGIN
    INSERT INTO log_tablename(@operation_id, ...) VALUES (@operation_id, ...);
END;

我知道这对MySQL不正确,但也许这个伪代码有助于澄清我的问题。

2 个答案:

答案 0 :(得分:1)

基于触发器的创建,您知道一些上下文:删除,插入,更新。

CREATE TRIGGER  <name_of_trigger>  
   [BEFORE | AFTER] 
   [UPDATE | INSERT | DELETE] -- Dictates context for trigger 'action'.
ON <table_name>
FOR EACH ROW BEGIN
  <SQL to execute>
END

如果您在日志中添加“操作”列,则可以告诉您使用了哪些操作将记录插入“更改”日志。

示例:

DELIMITER $$

-- Create Update,Insert,Delete triggers that logs the result of a table update to a log  
CREATE TRIGGER  trg_AFT_INS_table  AFTER UPDATE ON table
FOR EACH ROW BEGIN
  INSERT INTO table_log ( a, b, c, d, action)
  VALUES ( NEW.a, NEW.b, NEW.c, NEW.d, "update");
END $$
CREATE TRIGGER  trg_AFT_INS_table  AFTER INSERT ON table
FOR EACH ROW BEGIN
  INSERT INTO table_log ( a, b, c, d, action)
  VALUES ( NEW.a, NEW.b, NEW.c, NEW.d, "insert");
END $$
CREATE TRIGGER  trg_AFT_INS_table  AFTER DELETE ON table
FOR EACH ROW BEGIN
  INSERT INTO table_log ( a, b, c, d, action)
  VALUES ( OLD.a, OLD.b, OLD.c, OLD.d, "delete");
END $$

当记录表修改时,您可以讨论BEFORE vs AFTER ...我们发现使用'after'值使得日志与'二进制日志'有效相同,并且可以用于重建,包括最后一个修改,即记录所针对的表。

- J Jorgenson -

答案 1 :(得分:0)

使用MySQL general query log,它可以捕获已执行的确切语句。您可以choose将其写入文件或表格。