我在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不正确,但也许这个伪代码有助于澄清我的问题。
答案 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将其写入文件或表格。