You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

何时应在代码层而非数据库层实现软删除逻辑?

软删除逻辑应该放在数据库层还是代码层实现?

当公司政策要求对资源执行软删除时,行业内主流的实现位置分为两类,两类方案各有明确的优劣势,适用场景也有清晰的边界。

两类实现方案的具体差异

方案一:基于数据库触发器实现

几乎所有通用软删除技术文章都会优先推荐该方案,核心逻辑是通过数据库的删除触发器拦截所有硬删除请求,自动将删除操作替换为写入deleted_at时间戳的软删除操作。以PostgreSQL为例,实现代码如下:

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厂商发布的相关文章会主推代码层方案,本质是为了推广其自研ORM封装的软删除能力。
数据库触发器方案的核心优势包括:

  • API层代码和普通硬删除的写法完全一致,不需要额外封装软删除逻辑,JS侧调用示例如下:
// 查询构造器写法
Resource.query().deleteById(id);
// 原生数据库驱动写法
db.query('DELETE FROM resource WHERE id = $1;', [id]);
  • 具备全链路防误删能力:不管是业务代码、手动执行的SQL、第三方工具连库操作,只要触发删除请求都会被拦截转为软删除,从根源上避免意外硬删除。
  • 职责边界清晰:数据的存储、删除策略本身属于数据库层决策范畴,软删除后的数据原则上不属于应用正常访问范围,API层默认过滤掉deleted_at非空的数据即可,不需要感知软删除的具体实现,仅运维、开发人员在做数据找回、合规审计、数据分析时手动查询这部分数据。

该方案的缺点也很明确:

  • 逻辑属于隐式实现,不了解底层触发器配置的开发者很容易误以为执行的是硬删除,比如开发同事因为不知道触发器存在,看到DELETE语句就担忧数据被物理删除的情况十分常见。
  • 数据库侧逻辑的调试成本远高于应用层代码,虽然软删除触发器本身逻辑非常简单,但一旦出现边界问题,排查链路会比应用层代码长很多。

方案二:基于API代码层实现

该方案将软删除逻辑直接聚合在业务代码中,所有删除操作都显式执行更新deleted_at字段的逻辑,不存在隐藏的底层规则,JS侧调用示例如下:

// 查询构造器写法
Resource.query().findById(id).patch({deleted_at: new Date()});
// 原生数据库驱动写法
db.query('UPDATE resource SET deleted_at = now() WHERE id = $1;', [id]);

这种方案的优势是逻辑完全透明,所有业务规则都集中在代码层,新人接手不需要额外了解数据库侧配置,调试成本低。
核心缺点是完全不具备防呆能力:任何开发者只要写了原生DELETE语句、或者绕过封装好的软删除方法,就会直接执行硬删除,很容易出现误操作导致数据丢失。

代码层软删除的适用场景

不存在绝对最优的方案,以下三类场景优先选择代码层实现反而更合理:

  • 团队没有专职DBA,所有开发人员对触发器、存储过程等数据库特性熟悉度极低:这种情况下把逻辑放在代码层,所有人都能看懂、能调试,反而比藏在数据库里的触发器维护效率更高,也不会出现因为没人懂触发器规则导致的诡异问题。
  • 软删除逻辑和业务逻辑强绑定:比如部分业务场景下软删除需要同步触发发通知、写审计日志、级联更新关联表冗余字段等操作,这类逻辑放在代码层迭代、调试都更方便,放在数据库层反而会导致逻辑分散,维护成本陡增。
  • 团队有严格的数据库管控规范:很多中大型团队为了保证数据库可迁移性、降低运维风险,会禁止在数据库中编写业务逻辑,这种情况下代码层实现是唯一合规的选择。

多数文章优先推荐数据库层实现的核心原因

这背后不存在未被提及的隐藏坑,核心是两个非常实际的行业共识:

  • 数据安全优先级最高:对于绝大多数业务系统来说,误删数据带来的损失远大于逻辑隐式带来的沟通成本,数据库层实现是目前唯一能100%拦住所有意外硬删除的方案,只要配置了触发器,哪怕新人写错SQL、哪怕临时运维脚本执行出错,都不会真的物理删除数据。
  • 逻辑复用成本最低:触发器配置一次,所有连库的服务、脚本、工具都会自动遵循软删除规则,不需要每个服务、每个ORM、每个操作数据的场景都单独封装一遍软删除逻辑,从根源上避免某个场景漏封装导致硬删除的问题。

至于开发者对隐式逻辑的误解问题,本质不属于方案选型的问题,属于团队知识库建设的范畴:只要把数据库触发器配置、软删除规则写到团队开发规范中,新人入职时做对应的培训,这类问题完全可以避免,不需要为了沟通便利性牺牲数据安全底线。


内容的提问来源于stack exchange,提问作者BlueSialia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 12:45:25