如何在促进物理删除的同时促进数据的“软删除”?

时间:2019-01-30 14:00:00

标签: java mysql database hibernate mysql-workbench

我有一个带有表的MySQL数据库,其中一些表与外键互连。好吧,您可以在下面查看示例。

enter image description here

如果需要,我需要确保可以删除两个亲子。但是我还需要确保系统将执行软删除(只需标记为已删除,而无需物理删除它们),以便我们可以还原数据或将其用于分析。

  1. 我知道我可以通过启用ON DELETE CASCADE来轻松删除两个亲子。但是在这里,我可能会永远丢失成千上万的数据,并且将无法还原。如果删除是偶然的,那将是一团糟。

  2. 我知道我可以禁用ON DELETE CASCADE并将其他字段添加到数据库表中以标记记录deleted。因此,如果删除了一条记录,它将被简单地标记为已删除,并且不会显示在应用程序中,而会在数据库中显示。这种情况下的问题是,如果将parent标记为已删除,那么至少在我的系统中,我也必须将所有children标记为已删除。另一方面,如果我实际上要删除记录,那将是一个很大的麻烦,我将必须首先删除所有child记录。

那么什么是更好的选择?我对通过制作影子表,存档表,视图等来避免过于复杂也没有兴趣。

我能想到的最佳选择如下。

  1. 启用DELETE ON CASCADE。但是不要向一般用户公开记录delete方法。仅向管理员公开这些方法。

  2. 向表添加delete_flag字段。此字段将标记是否删除记录。向一般用户和管理员公开这些方法,因为它实际上不会删除任何内容。

请让我知道这种方法是好方法还是您有更好的选择?另外,如果我的方法更好,那么当父母的delete_flag更改时,如何更新孩子的delete_flag

1 个答案:

答案 0 :(得分:1)

这就是我处理这类事情的方式。

  1. 避免串级约束,

  2. 我在每个表上都放置了一个expiry_datestamp列。

  3. 我设置了实时数据查询,说AND (expiry_datestamp IS NULL OR expiry_datestamp < NOW())

  4. 软删除行时,我使用UPDATE ... SET expiry_datestamp = NOW()

  5. 这使您可以查看数据并查看最近被软删除的内容以及何时删除。

  6. 我通过在父记录之前显式删除子记录来创建清除程序以删除过期的东西。 (不依赖CASCADE CONSTRAINT功能)。这些程序可以每月或每周运行一次,也可以按您需要的时间表运行。

  7. 如果将新记录中的expiry_date值设置为将来的某个特定日期,可以简化(x IS NULL OR x < NOW())过滤器。

注意。当然,您可以使用deleted列来代替我更复杂的expiry_date方法。 如果您这样做,请确保您的查询说的是AND deleted = 0,而不是AND deleted <> 1。不等式过滤器的性能不及等式过滤器。

关于GDPR:这是一个真正的问题,而且很痛苦。如果您的策略说您在用户最后一次输入个人识别信息后三个月删除了该信息,则可以使清除程序处理该操作。您正确的认为产品信息不是个人信息。

编辑:我的过程:我不希望向Web应用程序用户授予MySQL特权,以硬删除行,而仅软删除行。在我的工作流程中,以更高的特权执行清除工作更安全。我避免使用CASCADE CONSTRAINTS,因为我不喜欢副作用:当它们违反约束时,我想捕获并停止DELETE(或UPDATE)。我相信创建清除程序以显式删除相关行是更安全和更好的编程习惯。

您可能有不同的首选项。