如何在事务数据库中存储已删除的行

时间:2011-04-19 08:17:13

标签: database-design unique-constraint transactional-database

这是对我的其他帖子中的heximal提出的评论的后续跟进。我希望有一个deleted_on列来检测已删除的记录,其中heximal表示此列是多余的。

以下是他的评论:

  

您将使用deleted_xx字段来确定该记录是否已删除?

      imho,最好也是最好的方法是添加记录布尔数据类型的某些活动属性(例如名为ACTIVE的字段)。因此,为了“删除”记录,我们必须在单个UPDATE查询中更新ACTIVE字段和update_dateupdated_by的值。为了选择所有活动记录,我们只需要进行如下查询:

     

SELECT * FROM MyTable WHERE ACTIVE = 1

     

我知道Oracle Applications使用这种方法,我同意

我还阅读了以下帖子:

我的问题是:如何在具有 isActive 标志的表上设置唯一约束,如上面的十六进制所示。我的所有表中都有代理键。但我想确保自然键列(我们称之为业务键列)具有唯一约束。

如果我有一个deleted_on字段来跟踪删除,那么我可以将此列包含为自然键约束的一部分。因此,它允许多个具有相同业务键组合的已删除记录,仅在deleted_on日期字段中有所不同。

如果我有isActive字段并使用last_updated_on列来跟踪删除日期,我必须在自然键约束上有2个选项

  1. 我可以将isActive作为我的自然键约束的一部分。但是这将允许最多只有一个已删除的记录具有相同的业务键组合。
  2. 我可以将isActivelast_updated_on作为自然键约束的一部分。但是我看到有一个额外的列deleted_on使它更容易。
  3. 有什么想法?我在这里错过了什么吗?

3 个答案:

答案 0 :(得分:1)

“我的问题是如何在具有isActive标志的表上设置唯一约束,如上面的heximal所示。我的所有表中都有代理键。但我想确保自然键列(我们称之为业务键列)具有唯一约束。

如果我有一个deleted_on字段来跟踪删除,那么我可以将此列包含为自然键约束的一部分。因此,它允许多个具有相同业务键组合的已删除记录,仅在deleted_on日期字段中有所不同。“

即使将deleted_on DATE字段作为自然键的一部分,您仍然无法在同一天删除 - 重新插入 - 全部删除。可能看似病态,但你真的可以确定病理情况永远不会发生吗?

如果您的数据库需要反映某些内容是“活跃的”这一事实,因为它与当前业务高度相关,而某些其他内容是“非活动的”,例如从某种意义上说,保留一段时间的唯一原因是出于档案目的,然后通过定义两个表来设计数据库以反映这一事实:一个具有“活动”内容,另一个具有“存档”内容。也许您可以使用触发器在发生删除时自动实现“移动到存档”。

这样,您可以使用“活动”表上的唯一约束使DBMS强制执行自然密钥,并且可以在“归档”表中包含删除时间戳,甚至可能不需要定义那张桌子上的任何钥匙。

答案 1 :(得分:0)

添加“VERSION”(整数)而不是ACTIVE列怎么样?

  • 当前(活动,未删除)版本为0
  • 无论何时用新版本替换当前版本,都要更新所有用VERSION替换VERSION的现有行(因此当前版本变为-1,先前当前版本变为-2,依此类推)然后用新INSERT删除当前版本VERSION = 0。

当然,此版本字段很容易成为自然键的一部分。

答案 2 :(得分:0)

当我记得我已经写过时,我正准备写一篇大文章 Are there problems with this 'Soft Delete' solution using EAV tables?
如果您想要的是一种撤消删除的简单方法,或者为审计/故障排除目的保留删除的跟踪记录,则使用镜像表是一种简单的解决方案。

Soft delete best practices (PHP/MySQL)
你需要考虑“删除”的真正含义。您似乎希望能够重建历史记录,在这种情况下,“删除”一词会导致混淆。这真的不是删除。您希望使用某种时态数据模型,并引入有效日期的概念。

或者,如果您只关心数据量,那么删除或移动超过X天/年的行的简单批处理也是一种非常简单的方法。