Answers:
是的,我肯定会选择第二个选项,但是我会在日期字段中再添加一个字段。
因此,您添加:
delete boolean
delete_date timestamp
这将使您有时间进行不删除操作。
如果时间少于一个小时,则可以取消删除。
要真正删除已删除的条目,只需创建一个存储过程即可,将delete设置为true且时间大于一小时,以清除每个条目并将其作为cron选项卡运行,每24小时运行一次
小时只是一个例子。
cleaned
或某物-指示与该记录关联的数据已正确,全面地删除。除非cleaned
为真,否则该记录可以不删除,在这种情况下,该记录将无法恢复。
deleted_at
同时包含delete
布尔值和delete_date
时间戳记的字段。如果deleted_at
为is ,则NULL
case delete
为FALSE
and delete_date
是NULL
,deleted_at
包含时间戳记;为case delete
,TRUE
并delete_date
包含时间戳,为您节省时间,存储和应用程序逻辑。
deleted
查询未删除的行时,对字段进行过滤后的索引可以大大提高性能
在我们的应用程序中,无论如何,我们并没有真正按照用户的要求删除任何内容(我们的客户处于受监管的环境中,在其中删除任何内容都可能导致法律问题)。
我们将较旧的版本保存在单独的审核表中(因此对于表some_table,其中的表也称为some_table_audit)是相同的,除了具有附加的版本标识符(如果DB支持足够细的时间值,则为时间戳,整数版本号)或作为通用审计表外键的UUID等),并通过触发器自动更新审计表(因此我们不需要使所有更新记录的代码都知道审计要求)。
这条路:
如果使用时间戳而不是(或同时使用)整数版本号,则可以根据需要在指定的时间后使用它来删除较旧的副本。但是这些天磁盘空间相对便宜,因此除非我们没有理由丢弃旧数据(即数据保护法规说您应该在X个月/年之后删除客户端数据),否则我们不会这样做。
此答案已有大约几年的时间,此后已经改变了一些可能影响此类计划的关键因素。我不会详细介绍,只是为了今天阅读此书的人们的利益:
SQL Server 2016引入了“系统版本化的时态表”,该表为您完成了许多工作,此外还提供了一些不错的语法糖,以使历史查询更易于构建和维护,并且它们协调了之间的架构更改子集。基本表和历史记录表。他们并非没有警告,但它们是实现此目的的有力工具。在其他数据库系统中也可以使用类似的功能。
数据保护法规的变化,尤其是GDPR的引入,可以显着改变何时应该硬删除数据的问题。在考虑时,您必须权衡不删除可能对审核目的有用(或确实是法律上要求)的数据与在考虑考虑时需要尊重人民权利(既包括一般性法律又明确规定相关法律)的平衡您的设计。这可能是系统版本化的时态表的问题,因为您无法修改历史记录以清除个人数据,而无需进行模式短期更改即可在进行更改时关闭历史记录跟踪。
与Spredzy建议的类似,我们在所有应用程序中都使用时间戳字段进行删除。布尔值是多余的,因为设置了时间戳记表明该记录已被删除。这样,我们的PDO总是添加AND (deleted IS NULL OR deleted = 0)
到select语句中,除非模型明确要求包括已删除的记录。
目前,除了包含Blob或文本的表格外,我们不会对任何其他表格进行垃圾回收;如果对记录进行了很好的规范化,那么空间就deleted
很小了,对字段进行索引对选择速度的影响有限。
我过去经常在表行中看到像“ DeletedDate”这样的列,但我不喜欢它们。“删除”的概念是,不应首先输入该条目。实际上,它们无法从数据库中删除,但我不希望它们与我的热数据一起使用。根据定义,逻辑上删除的行是冷数据,除非有人特别希望看到删除的数据。
此外,编写的每个查询都必须专门排除它们,索引也需要考虑它们。
我希望看到的是数据库体系结构级别和应用程序级别的更改:创建一个称为“已删除”的架构。每个用户定义的表在“已删除”模式中具有相同的等效项,带有一个额外的字段来保存元数据-删除该表的用户以及删除该表的时间。需要创建外键。
接下来,删除变为插入删除。首先,将要删除的行插入其“已删除”架构对应项中。然后可以删除主表中的相关行。但是,确实需要在该行的某个地方添加额外的逻辑。可以处理违反外键的行为。
必须正确处理外键。不好的做法是在逻辑上删除行,但其主/唯一行在引用该表的其他表中具有列。无论如何这都不应该发生。常规作业可以删除寡妇行(尽管存在外键,但其主键在其他表中没有引用的行。但是,这是业务逻辑)。
总体好处是减少了表中的元数据并带来了性能提升。“ deletedDate”列表示该行实际上不应该在此处,但是为了方便起见,我们将其保留在此处并让SQL查询对其进行处理。如果已删除行的副本保留在“已删除”模式中,则包含热数据的主表将具有较高百分比的热数据(假设它已及时存档),并且不必要的元数据列会更少。索引和查询不再需要考虑此字段。行大小越短,页面上可以容纳的行数越多,SQL Server可以运行得越快。
主要缺点是操作的大小。现在有两种操作,而不是一种,还有额外的逻辑和错误处理。与更新否则将导致更新的单列相比,它可能导致更多的锁定。事务在表上的锁定时间更长,并且涉及两个表。至少以我的经验,删除生产数据很少完成。即便如此,在主表之一中,近1亿个条目中有7.5%的“ DeletedDate”列中有一个条目。
作为对该问题的解答,应用程序必须知道“取消删除”。只需按照相反的顺序进行操作:将“已删除”模式中的行插入主表,然后从“已删除模式”中删除行。再次需要一些额外的逻辑和错误处理,以确保避免错误,外键问题等。