0

在表 T 中插入新行时,我想检查表是否大于某个阈值,如果是,则删除最旧的记录(最终创建某种 FIFO)。

我以为我可以简单地制作一个触发器,但显然 MySQL 不允许修改我们实际插入的表:

Code: 1442  Msg: Can't update table 'amoreAgentTST01' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.

这是我尝试过的触发器:

Delimiter $$ 
CREATE TRIGGER test 
       AFTER INSERT ON amoreAgentTST01
       FOR EACH ROW
BEGIN
    DECLARE table_size INTEGER;
    DECLARE new_row_size INTEGER;
    DECLARE threshold INTEGER;
    DECLARE max_update_time TIMESTAMP;

SELECT SUM(OCTET_LENGTH(data)) INTO table_size FROM amoreAgentTST01;
SELECT OCTET_LENGTH(NEW.data) INTO new_row_size;
SELECT 500000 INTO threshold;
select max(updatetime) INTO max_update_time  from amoreAgentTST01;

IF (table_size+new_row_size) > threshold THEN
   DELETE FROM amoreAgentTST01 WHERE max_update_time = updatetime; -- and check if not current
END IF;
END$$
delimiter ;

您对如何在数据库中执行此操作有任何想法吗?

或者这显然是我的程序中要做的事情?

4

1 回答 1

4

理想情况下,您应该在非高峰时间运行的单独进程中制定专门的归档策略。

您可以将其实现为计划存储过程 (yuck) 或应用程序服务器中的附加后台工作线程,或完全独立的应用程序服务。这将是放置其他常规家政工作的好地方。

这有几个好处。除了避免您看到的触发器问题之外,您还应该考虑触发器中发生的任何事情对性能的影响。如果您执行多次插入,该触发器将完成这项工作并有效地降低一半的性能,更不用说当其他进程尝试访问同一个表时会出现的锁争用。

执行内务处理工作的单独进程可最大限度地减少锁争用,并允许在事务中将工作作为高性能批量操作执行。

最后一件事 - 您可能应该考虑将记录归档到另一个表或数据库,而不是删除它们。

于 2009-04-01T15:49:55.603 回答