Database design 如何在事务数据库中存储已删除的行
这是对heximal在我的另一篇文章中提出的评论的跟进。我想在列上设置一个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
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产品中都不可行。但是,如果您在主表中更改了布尔标志或设置了删除日期,您将如何处理这些引用行?在涉及联接的查询中,您是否仍在联接那些伪删除的行,或者您是否会主动跳过这些行,即使引用行本身仍然处于活动状态?两者看起来都不对。