通过设置is_deleted字段并使用索引来删除数据库中的字段

时间:2009-12-23 18:20:56

标签: database-design

我正在编写一个应用程序,我希望通过将数据库中的is_deleted字段设置为true来删除记录,并且默认为false。

这个工作正常,但是当我索引唯一的另一个字段时我遇到了一个问题我无法插入具有相同条目的字段,尽管旧的字段实际上已删除但不是从DB的角度来看。

你知道解决方案吗?

谢谢,

6 个答案:

答案 0 :(得分:5)

另一种选择是将列更改为日期字段,例如deleted_at。在身份+日期上创建唯一约束应该足够独特。

答案 1 :(得分:3)

如果您想“重复使用”已删除行的“身份”,那么当您“软删除”一行时,您必须清除该身份字段(无论它是什么)。在我看来,这不是一个好主意,因为如果你有什么要取消删除那一行 - 那么什么?

为什么要重用这些身份?我会远离这样的结构 - 只要给每一行都有自己的身份 - 无论是活动的还是删除的 - 并且不要重复使用预先存在的身份。不是一个好习惯!

答案 2 :(得分:1)

如果您需要能够重复使用标识符,那么您的数据库不应该对该列具有唯一约束。您的申请必须保证唯一性;如果你真的想要数据库这样做,我能想到的唯一方法就是一个能够验证唯一性的触发器,但只能在IsDeleted = 0的列上进行验证。

答案 3 :(得分:1)

正如其他人所提到的那样,没有一种非常好的方法可以做到这一点。即使跨越is_deleted和标识字段跨越唯一索引,您仍然一次只能有一个已删除的对象。

另一种方法是添加一个非唯一字段,id将被分配到该字段。要删除某些内容,您可以运行以下内容:

update table
   set old_id = id, id = null, is_deleted = 1
 where id = ?

要恢复它,正如海恩斯先生所说,安装与拆除程序相反。

请注意,某些数据库( cough MSSQL cough )在唯一约束列中不允许多个NULL值,因此您必须更加聪明。

答案 4 :(得分:0)

is_deleted和您实际需要唯一的其他字段组合制作唯一索引。

答案 5 :(得分:0)

我不会使用Pavel的方法,因为你无法删除第二行(因为第一列已经是ID和FALSE的组合键)。

因此,如果您需要具有唯一ID,请创建一个真正唯一的标识列。您当前的id列不仅仅是索引(允许重复)。听起来您当前的ID列是外部ID,因此请对其进行相应的处理。