在SQL数据库中强制执行表保留策略的最佳位置?

时间:2012-04-30 22:29:02

标签: sql sql-server database

我有一张记录客户联系信息的表格。该表仅定义为“最近”的联系人,我想删除超过3周的联系人的所有记录。

例如,表格是:

create table recent_contact {
   recent_contact_id int identity (1,1) primary key,
   contact_text nvarchar(4000),
   created datetime
}

create index createdIndex
on recent_contact (created)

此表的所有插入都将通过只执行INSERT语句的存储过程进行。

我的问题是关于清理。我想删除超过3周的所有商品。到目前为止,我已经想到了两种方法来完成清理工作。

  1. 定期运行后台数据库作业(例如每5个小时),扫描上表并删除超过3周的任何内容。

  2. insert()存储过程调用中,添加逻辑以清除旧数据。这应该只添加恒定的时间开销,因为表已在[created]上建立索引,并且每个项目都插入一次并且只删除一次。因此,平均而言,这个sproc将执行1次插入和1次删除。

  3. // insert
    insert into recent_contacts (contact_text, created)
    values (@text, @createDate)
    
    declare @threeWeeksAgo datetime
    set @threeWeeksAgo = DATEADD(DAY, -21, GETDATE())
    
    // remove old items
    delete from recent_contacts 
    where created < @threeWeeksAgo
    

    在这两个选项中,我选择了2)因为我觉得这是一个更优雅的解决方案,不需要单独的清理工作。我的同事告诉我,这是不好的做法,保留政策应始终在一个单独的工作,定期运行。即他认为选项1)是更好的选择。

    我想知道别人怎么想?一般而言,实施数据保留政策的最佳做法是什么?

2 个答案:

答案 0 :(得分:2)

做1)。选项2)是一个被误导的想法。没有理由避开定期工作,但是有很多理由可以避免惩罚每一个插件以及查找过时条目的成本,甚至更多惩罚INSERT随机响应时间的高峰,因为这是不吉利的清理一些条目的彩票的获胜者。另一方面,预定的工作可以在方便的时间安排。而且,最后但同样重要的是,考虑到您的“聪明”设计需要INSERT才能进行维护。

随着时间的推移,您将了解到由于index tipping point问题,保留期后数据的清理实际上是一个非常棘手的问题,并且许多开发人员正在铺平道路。您还会在时间列中发现时间序列,如聚簇索引,而不是因为过时的数据清理问题。

答案 1 :(得分:2)

我选1)因为:

  • 最好有专门的清理旧数据的过程。使用2),您在一个例程中交织了两个进程,如果(当)一个进程发生更改,您将只需修改代码的那一部分而不会弄乱另一个部分。
  • 类似的,如果它以某种方式破裂会发生什么?通过两个过程,如果有什么事情发生,你可能会将必要的故障排除工作增加一倍。
  • 如果出于某种原因(停电,假期,淡季),没有人会进入新行,会发生什么?您的数据不在保留窗口中,但仍保留在系统上。

根据代码库的大小和数据的总体数量(我猜这些数据非常小),这些比其他任何东西都更加狡辩(除非随着时间的推移,音量会显着增长......)即便如此,使用“更安全”战术现在建立了良好的习惯和做法,所以如果有一天你必须使用大容量系统,你就更有可能在第一次通过时产生适当强大的代码。