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

Database design 如何在事务数据库中存储已删除的行,database-design,unique-constraint,transactional-database,Database Design,Unique Constraint,Transactional Database,这是对heximal在我的另一篇文章中提出的评论的跟进。我想在列上设置一个deleted\u,以检测已删除的记录,heximal认为该列是多余的 以下是他的评论: 您要使用deleted\u xx字段来确定记录是否已删除 总之,最好也是最好的方法是添加一些布尔数据类型的活动属性(例如,名为ACTIVE)来记录。因此,为了“删除”记录,我们必须在单个更新查询中更新ACTIVE字段和update\u date,updated\u by的值。为了选择所有活动记录,我们只需进行如下查询: 从MyTabl

这是对heximal在我的另一篇文章中提出的评论的跟进。我想在列上设置一个
deleted\u,以检测已删除的记录,heximal认为该列是多余的

以下是他的评论:

您要使用
deleted\u xx
字段来确定记录是否已删除

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

从MyTable中选择*ACTIVE=1

我知道Oracle应用程序使用这种方法,我也同意

我还阅读了以下帖子:

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

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

如果我有
isActive
字段,并在
列上使用
last\u updated\u跟踪删除日期,我必须在自然关键点约束上有两个选项

  • 我可以将
    isActive
    作为自然关键点约束的一部分。但这将只允许max使用相同的业务密钥组合删除一条记录
  • 我可以将
    isActive
    加上
    last\u updated\u on
    作为自然关键点约束的一部分。但我发现删除一个额外的列会更容易
  • 有什么想法吗?我在这里遗漏了什么吗?

    添加一个“版本”(整数)而不是一个活动列怎么样

    • 当前(活动、未删除)版本为0
    • 无论何时用新版本替换当前版本,都会更新所有现有行,用版本1替换版本(因此当前版本变为-1,以前的当前版本变为-2,依此类推),然后插入版本为0的新当前记录
    当然,这个版本字段可以很容易地成为自然键的一部分。

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

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

    即使将删除日期字段作为自然密钥的一部分,您仍然无法在同一天删除所有内容。可能看起来是病态的,但你真的能肯定这种病态的情况永远不会发生吗

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


    这样,DBMS就可以在“活动”表上使用一个唯一的约束来强制您的自然密钥,并且您可以在“存档”表中包含一个删除时间戳,您甚至可能根本不需要在该表上定义任何密钥。

    我正要写一篇大文章,但我记得我已经在
    中写过了
    如果您想要的是一种撤消删除的简单方法,或者为了审计/故障排除目的保留删除的跟踪记录,那么使用镜像表是一种简单的解决方案


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


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

    这将导致每次有新的删除时进行大量更新,除非有巨大的好处,否则我不希望这样做。在自然需要版本控制的情况下,这是有意义的。但在这里,我看不到任何理由。谢谢你的想法。已删除的将有一个时间戳-因此,可以处理病理情况:)。为每个表创建两个表会带来更多的问题-如果已删除和存档的表仍然被另一个表引用会怎么样?那么无论如何,您会遇到SQL无法处理的RI问题。如果SQL功能强大,那么您可以定义一个“活动”和“存档”结合的视图,并让您的FK引用该视图。唉,在我所知道的任何SQL产品中都不可行。但是,如果您在主表中更改了布尔标志或设置了删除日期,您将如何处理这些引用行?在涉及联接的查询中,您是否仍在联接那些伪删除的行,或者您是否会主动跳过这些行,即使引用行本身仍然处于活动状态?两者看起来都不对。