我正在尝试创建一个考虑到历史的数据库(经验表明你有一天或另一天必须这样做)。
我在这里问过database-design-how-to-handle-the-archive-problem但没有比这里的链接更好的分析器了。
我的问题是关于在哪里编写代码以及在技术上如何编写代码(MySQL 让我头疼)。首先,我已经开始在 PHP 中执行此操作:在进行任何插入之前,复制记录并将其标记为“过时”,然后修改记录。
但是有一个依赖问题(manytomany 和 manytoone 关联也必须更新),这意味着编码(一种或另一种方式)表附带的所有依赖项和更新(这是不可接受的)。
所以我正在考虑在数据库服务器端完成所有工作。这将大大简化我的 PHP 代码。
问题是我必须在修改当前记录之前“存档”它。为此,代码必须在“更新前”触发器中。
这是我的代码:
DELIMITER ;;
DROP TRIGGER IF EXISTS produit_trigger_update_before;
CREATE TRIGGER produit_trigger_update_before
BEFORE UPDATE ON produit
FOR EACH ROW BEGIN
/* */
INSERT INTO produit SET
id_origine = OLD.id_origine,
date_v_creation = OLD.date_v_creation,
date_v_start = OLD.date_v_debut,
date_v_end = NOW(),
...
last_record = OLD.last_record;
/* Dependancies : */
SET @last=LAST_INSERT_ID();
UPDATE categorie_produit SET id_produit=@last
WHERE id_produit = OLD.id;
UPDATE produit_attribut SET id_produit=@last
WHERE id_produit = OLD.id;
END;;
DELIMITER ;;
如果我让这段代码工作,我所有的问题都消失了。但该死的,它不起作用:
mysql> update produit set importance=3;
ERROR 1442 (HY000): Can't update table 'produit' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
mysql> Bye
在此页面中有一个工作示例,它INSTEAD OF UPDATE
在触发器中使用了子句。MySQL 似乎不支持这一点。
所以我的问题既是概念性的(=你有任何其他可以工作的“原则”)和/或技术性的(=你能让这个触发器工作吗)。