【问题标题】:SQL trigger for deleting old results删除旧结果的 SQL 触发器
【发布时间】:2010-09-14 12:14:55
【问题描述】:

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

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

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

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

【问题讨论】:

    标签: sql sqlite


    【解决方案1】:

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

    【讨论】:

    • 一般来说这是正确的,但问题指定了一个嵌入式设备,所以我们不能假设有任何机制可以做到这一点,或者如果它是可取的。
    • Cruachan 对平台的看法是正确的。此外,触发器本身并不是真正的问题。这是我遇到麻烦的删除部分。这将是相同的,即使我将其作为单独线程的一部分。
    【解决方案2】:

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

    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;
    

    【讨论】:

      【解决方案3】:

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

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

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

      【讨论】:

      • 这对我不起作用有几个原因。首先,我们在系统中始终没有准确的时间和日期戳。另外,我需要失败和传递的正确关系。
      【解决方案4】:

      这个怎么样:

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

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

      【讨论】:

      • 这不是我想要的,因为如果你在 1000 次中有 50 次失败,那么你不需要在这之后保留更多失败。但是,标准可能实际上并不需要那么复杂。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-29
      • 1970-01-01
      相关资源
      最近更新 更多