MySQL触发器:如果表变得太大,是否可以删除行?

时间:2009-04-01 15:46:29

标签: mysql sql triggers mysql-error-1442

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

我以为我可以简单地触发,但显然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 ;

您是否知道如何在数据库中执行此操作?

或者显然我的计划要做些什么?

1 个答案:

答案 0 :(得分:4)

理想情况下,您应该在非高峰时段运行的单独流程中拥有专用的归档策略。

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

这有一些好处。除了避免你看到的触发器问题,你应该考虑触发器中发生的任何的性能影响。如果你做了很多插入操作,那么这个触发器就能完成这项工作并有效地降低一半的性能,更不用说其他进程试图访问同一个表时会出现的锁争用。

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

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