我有以下问题:
我想创建一个历史 - 但动态
所以我有一个现有的历史 - 触发器像: how to write mysql trigger
但我正在寻找解决方案,如:
INSERT INTO History VALUES ( NOW(), 'action', NEW.* )
如果行按主表排序 - 不管我如何插入它们?或者他们呢?
我不知道这个解决方案是否有效 - 所以在我在商业中使用它之前 - 我想确定它是否有用 - 或者我是否应该更新Trigger如果我'改变'表结构。
首先感谢您的回答 - 因为我无法回答这个问题 - 因为我是新手 - 我编辑了我的第一个声明:
那是怎么回事:
....插入历史值(现在选择(),'插入',新。* FROM new)....
答案 0 :(得分:1)
简答:
更好的选择是为MySQL使用审核插件。然后你根本不必编写触发器。
不支持您所展示的VALUES子句中元素的通配符语法(如您所知)。
那是怎么回事:
....插入历史值(现在选择(),'插入',新。* FROM new)....
没有。
此语法不仅无效(您无法从NEW中选择),但无论如何您还需要在历史记录表中添加额外的列。
可以设计触发器以从INFORMATION_SCHEMA.COLUMNS查询列集,并使用GROUP_CONCAT将逗号分隔的列表放在一起以包含在动态SQL INSERT语句中。
但是我永远不会把它放到生产系统中,因为查询I_S.COLUMNS的开销非常高,如果你的触发器每次插入,更新或者每次都执行时都会对性能成本感到满意删除表。
我咨询了一个因此问题无法扩展的网站。他们使用动态SQL运行大量存储过程,使用I_S验证每个表名和列名。因此,他们的数据库服务器与CPU负载挂钩,这对他们的持续增长来说是个大问题。
我会设计触发器来对列名进行硬编码。如果更改表格,则必须重新设计触发器。
考虑与触发器执行频率相比,您更改表的频率。它大概是1:10 ^ 9。
答案 1 :(得分:0)
我可能有一个解决方案,并会对您的意见感兴趣。 最初的目的是避免重复插入语句中的选择列表所产生的冗余,以及在表更改时重新创建触发器的必要性。 如果满足一些预备知识,可以避免这种情况:
历史记录表的开头应该有其他属性。 历史表的其余部分必须设计为原始表。 此外,您必须具有可用于查询的原始主键。然后:
!(*2*)
其他字段是标记和用户。
然后是触发器:
create table A (`id` bigint(20) AUTO_INCREMENT , a varchar(100), PRIMARY KEY (`id`))
create table AH (flag bit(1), user varchar(100), `id` bigint(20) , a varchar(100))
似乎做了预期的事。
即使在: alter table添加列(c varchar(200))
DELIMITER $$
CREATE TRIGGER `T` AFTER INSERT
ON `A` FOR EACH ROW BEGIN
INSERT INTO AH select 1, user(), mn.* from A mn where id = NEW.id;
END
$$
DELIMITER ;
触发器不变。