何时在数据库上的代码中实现软删除逻辑?



当我想软删除资源作为我公司的一项政策时,我可以在两个地方之一进行。

我可以在我的数据库中使用一些"而不是DELETE"触发器。像这样:

CREATE TRIGGER prevent_resource_delete
BEFORE DELETE ON resource
FOR EACH ROW EXECUTE PROCEDURE resource_soft_delete();
CREATE FUNCTION resource_soft_delete() RETURNS trigger
LANGUAGE plpgsql AS
$$
BEGIN
UPDATE resource SET deleted_at = now() WHERE id = OLD.id;
RETURN NULL;
END;
$$;

几乎每篇关于软删除的文章都建议这样做。除了由ORM所有者专门撰写的文章,因为他们有自己的内部解决方案。

我喜欢这个方法。我的api中的逻辑看起来就像我只是在删除资源。

Resource.query().deleteById(id); // Using a query builder
db.query('DELETE FROM resource WHERE id = $1;', [id]); // Using native library

对我来说,这似乎更自然,我不必担心其他开发人员意外地硬删除的东西。但对于那些不知道到底发生了什么的人来说,这也会让他们感到困惑。在数据库中有任何逻辑意味着我可能有错误(软删除逻辑通常是非常简单的,但仍然…),这将很难调试。至少与我的api中的那些相比。

但是我也可以在api本身中使用逻辑。一个逻辑接一个逻辑。没那么优雅,但更直接。没有隐藏的逻辑。我确实失去了防止人们意外地硬删除资源的保护。

Resource.query().findById(id).patch({deleted_at: new Date()}); // Using a query builder
db.query('UPDATE resource SET deleted_at = now() WHERE id = $1;', [id]); // Using native library

当我考虑是否软删除数据库问题时,我倾向于选择前者。数据库选择如何处理已删除的数据。删除的数据,无论是软数据还是硬数据,原则上都不再是应用程序的一部分。api无法检索它。这是我,开发人员,用于分析,法律原因或手动帮助想要恢复他/她认为丢失的东西的用户。

但是我不喜欢它的缺点。我刚和一个同事谈过,他很担心,因为他认为我们真的在删除东西。现在,这实际上可以通过更好的培训和文档来解决。但应该是这样吗?

何时在数据库上的代码中实现软删除逻辑?为什么我找到的每篇文章都直接建议使用数据库而不考虑代码?似乎有一个我找不到的强有力的理由。

在我看来,没有什么强有力的理由,这取决于架构师和开发人员决定把逻辑放在哪里,但下面可能是背后的原因::

首先,当我们从DB中删除一些东西时,所以保持逻辑在最适合的地方,

第二,为每个API编写逻辑是一种冗余,而不是在DB中做一次,为所有表或节点或集合做的工作更少。:)

最新更新