如何通过BEFORE UPDATE触发器在MySQL中归档MySQL数据库的历史版本记录?
- 内容介绍
- 文章标签
- 相关推荐
本文共计718个文字,预计阅读时间需要3分钟。
在执行更新操作前,不能直接依赖触发器将旧值存储到另一张表中。触发器本身并不保存旧值到其他表,它仅执行逻辑。为了保存旧记录,你需要显式地执行以下SQL语句:
触发器里怎么安全地插入旧记录?关键三点
很多线上事故源于触发器内操作没兜住异常或锁冲突。以下不是建议,是必须检查的底线:
-
archive_table必须和原表在同一个数据库、同一实例内;跨库INSERT在BEFORE UPDATE中可能失败(尤其开启binlog_format=ROW时) - 不要在触发器里调用存储过程或复杂函数——它们可能隐式开启事务或加锁,导致主表更新被阻塞
-
OLD.*只在BEFORE UPDATE和BEFORE DELETE中有效,AFTER触发器里已不可用;想存变更前快照,只能用BEFORE
为什么归档表主键不能直接用原表主键?
因为同一条记录可能被反复更新,每次都会生成一条旧记录。如果 archive_table 主键仍设为 id(原表主键),第二次更新就会因主键冲突报错:Duplicate entry '123' for key 'PRIMARY'。
本文共计718个文字,预计阅读时间需要3分钟。
在执行更新操作前,不能直接依赖触发器将旧值存储到另一张表中。触发器本身并不保存旧值到其他表,它仅执行逻辑。为了保存旧记录,你需要显式地执行以下SQL语句:
触发器里怎么安全地插入旧记录?关键三点
很多线上事故源于触发器内操作没兜住异常或锁冲突。以下不是建议,是必须检查的底线:
-
archive_table必须和原表在同一个数据库、同一实例内;跨库INSERT在BEFORE UPDATE中可能失败(尤其开启binlog_format=ROW时) - 不要在触发器里调用存储过程或复杂函数——它们可能隐式开启事务或加锁,导致主表更新被阻塞
-
OLD.*只在BEFORE UPDATE和BEFORE DELETE中有效,AFTER触发器里已不可用;想存变更前快照,只能用BEFORE
为什么归档表主键不能直接用原表主键?
因为同一条记录可能被反复更新,每次都会生成一条旧记录。如果 archive_table 主键仍设为 id(原表主键),第二次更新就会因主键冲突报错:Duplicate entry '123' for key 'PRIMARY'。

