1

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

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

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

编辑:澄清一下,我遇到问题的部分是删除,特别是与最近 50 次故障相关的部分。

4

4 回答 4

1

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

于 2008-10-01T12:04:52.630 回答
0

到目前为止,我最终使用了结合触发器的视图,但由于其他原因,我不确定它是否会起作用。

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;
于 2008-10-01T12:07:48.457 回答
0

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

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

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

于 2008-10-01T12:19:58.863 回答
0

这个怎么样:

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

如果性能是一个问题,最好定期删除,而不是每次插入。

于 2008-10-02T14:25:20.130 回答