用于删除旧结果的SQL触发器

时间:2008-10-01 12:03:12

标签: sql sqlite

我们有一个数据库,用于存储嵌入式设备的测试结果。有一个表格,其中包含不同类型故障的列(详情不相关),以及主键“keynum”和列出失败次数的“NUM_FAILURES”列。我们存储传球和失败,因此传球在'NUM_FAILURES'中有一个'0'。

为了防止数据库不受限制地增长,我们希望保留最后1000个结果,以及最后50个超出1000的失败。所以,最坏的情况是,表中可能有1050个条目。我正在尝试找到最有效的SQL插入触发器来删除额外的条目。到目前为止,我会给出答案,但我希望看看是否有人可以提出更好的东西,因为SQL不是我经常做的事情。

我们在非Windows平台上使用SQLITE3,如果它是相关的。

编辑:为了澄清,我遇到问题的部分是DELETE,特别是与最近50次失败相关的部分。

4 个答案:

答案 0 :(得分:1)

您要删除这些条目的原因是为了使数据库保持过大而不是将其保持在某种特殊状态。为此,我真的不会使用触发器,而是设置一个工作,以一定的间隔运行清理表。

答案 1 :(得分:0)

到目前为止,我最终使用了View和Trigger,但我不确定它是否会因其他原因而起作用。

CREATE VIEW tablename_view AS SELECT keynum FROM tablename WHERE NUM_FAILURES!='0' 
    ORDER BY keynum DESC LIMIT 50;
CREATE TRIGGER tablename_trig
  AFTER INSERT ON tablename WHEN (((SELECT COUNT(*) FROM tablename) >= 1000) or
    ((SELECT COUNT(NUM_FAILURES) FROM tablename WHERE NUM_FAILURES!='0') >= 50))
  BEGIN
     DELETE FROM tablename WHERE ((((SELECT MAX(keynum) FROM ibit) - keynum) >= 1000)
  AND 
     ((NUM_FAILURES=='0') OR ((SELECT MIN(keynum) FROM tablename_view) > keynum)));
  END;

答案 2 :(得分:0)

我认为您可能使用了错误的数据结构。相反,我会创建两个表并预先填充一个1000行(成功),另一个表示50(失败)。在每个上放一个主要ID。当您记录结果而不是插入新行时,会找到输入的最后一个时间戳记录的ID + 1值(如果表中的> max(id),则循环回0)并使用新值更新它。

这具有预先分配存储,不需要触发器和内部一致逻辑的优点。您还可以通过预先填充更多记录而不必更改程序逻辑来非常简单地调整日志大小。

您可以使用多种变体,但使用闭环结构而非开放列表的想法似乎更接近问题域。

答案 3 :(得分:0)

这个怎么样:

DELETE  
FROM  table 
WHERE ( id   > ( SELECT max(id) - 1000 FROM table ) 
        AND  num_failures   = 0 
      )
OR    id     > ( SELECT max(id) - 1050 FROM table ) 

如果考虑性能,最好定期删除,而不是每次插入。