问题
在处理产品和订单的Web应用程序中,我希望维护前员工(用户)与他们处理的订单之间的信息和关系。我希望维护过时的产品和包含这些产品的订单之间的信息和关系。
但是,我希望员工能够解除管理界面的混乱,例如删除以前的员工,过时的产品,过时的产品组等。
我正在考虑实施软删除。那么,人们通常如何做到这一点?
我的直接想法
我的第一个想法是在应该是软删除的每个对象表中粘贴一个“flag_softdeleted
TINYINT NOT NULL DEFAULT 0”列。或者也许使用时间戳?
然后,我在每个相关的GUI中提供“显示已删除”或“取消删除”按钮。单击此按钮,您将在结果中包含软删除的记录。每个删除的记录都有一个“恢复”按钮。这有意义吗?
你的想法?
此外,我很感激任何相关资源的链接。
答案 0 :(得分:32)
我就是这样做的。我有一个is_deleted
字段,默认为0.然后查询只检查WHERE is_deleted = 0
。
我尽量远离任何难以删除的东西。它们有时是必要的,但我将其设为仅限管理员的功能。这样我们就可以硬删除,但是用户不能......
编辑:实际上,您可以使用此功能在您的应用中拥有多个“软删除”层。所以每个都可以是代码:
0
- >未删除1
- >软删除,显示在管理用户的已删除项目列表中2
- >软删除,不会显示除管理员用户以外的任何用户3
- >仅显示给开发人员。拥有其他2个级别仍然允许管理员和管理员清理已删除的列表,如果它们太长时间。由于前端代码只检查is_deleted = 0
,因此它对前端是透明的...
答案 1 :(得分:8)
使用软删除是很常见的事情,它们对许多事情都很有用,例如:
我想指出的一件事是,几乎所有人都会想念,而且它总是会让你回到后面。您的应用程序的用户对 delete 的理解与您没有相同的理解。
删除有不同的度。典型的用户在
时删除东西问题在于,如果您没有记录删除的意图,那么您的应用程序无法区分错误的数据(应该永远不会创建)和历史上正确的数据。
查看以下数据:
PRICES | item | price | deleted |
+------+-------+---------+
| A | 101 | 1 |
| B | 110 | 1 |
| C | 120 | 0 |
+------+-------+---------+
某些用户不想显示商品B的价格,因为他们不再销售该商品。所以他删除了它。另一个用户通过误导为物品A创建了价格,因此他将其删除并按预期为物品C创建了价格。现在,您能告诉我所有产品的价格清单吗?不,因为要么必须显示潜在的错误数据(A),要么必须排除除当前价格之外的所有数据(C)。
当然,上述内容可以通过多种方式处理。我的观点是你需要非常清楚你对删除的意思,并确保用户无法理解它。一种方法是强制用户做出选择(隐藏/删除)。
答案 2 :(得分:5)
如果我有现有的代码命中该表,我会添加该列并更改表的名称。然后我将创建一个与当前表同名的视图,该视图仅选择活动记录。这样,现有的代码都没有破坏,你可以拥有软删除列。如果要查看已删除的记录,请从基表中进行选择,否则使用视图。
答案 3 :(得分:1)
我总是只使用您提到的已删除列。它确实没有那么多。只需将已删除的字段设置为true即可,而不是删除记录。
我构建的某些组件允许用户查看所有已删除的记录并将其还原,其他组件只显示已删除的所有记录 = 0
答案 4 :(得分:1)
您的想法确实有意义且经常在生产中使用,但为了实现它,您需要更新相当多的代码来解释新字段。另一种选择是将“软删除”记录存档(移动)到单独的表或数据库。这也经常完成,并使问题成为维护而不是(重新)编程。 (您可以让表触发器对删除做出反应以存档已删除的记录。)
我会进行归档以避免对生产代码进行重大更新。但是,如果您想使用deleted-flag字段,请将其用作时间戳,以便为您提供超出布尔值的其他有用信息。 (Null =未删除。)您可能还想添加DeletedBy字段以跟踪负责删除记录的用户。使用两个字段可以为您提供大量信息,告诉您谁删除了什么以及何时删除。 (这两个额外的字段解决方案也可以在存档表/数据库中完成。)
答案 5 :(得分:0)
我遇到的最常见情况是您所描述的内容,tinyint
甚至bit
代表状态IsActive
或IsDeleted
。根据这被认为是“业务”还是“持久性”数据,它可以尽可能透明地烘焙到应用程序/域逻辑中,例如直接在存储过程中并且应用程序代码不知道。但听起来这是符合您需求的合法商业信息,因此需要在整个代码中了解。 (因此,如您所建议,用户可以查看已删除的记录。)
我看到的另一种方法是使用两个时间戳的组合来显示给定记录的活动“窗口”。维护它的代码要多一些,但好处是可以安排某些东西在预定的时间进行软删除。例如,限时产品可以在创建时以这种方式设置。 (为了使记录无限期激活,可以使用最大值(或者只是一些荒谬的遥远的未来日期),或者如果您对此结果正确,则结束日期为null
。)
当然,还会不时考虑删除/取消删除的内容并跟踪某种审计。标志方法只知道当前状态,时间戳方法只知道最近的窗口。但是,任何像审计线索一样复杂的事情都应该与有关记录分开存储。