在数据库设计中,当删除一条记录的时候,是加一个标记位还是直接删除这一行?

物理删除:真删除,数据消失。
逻辑删除:假删除,数据存在,只是用一个字段来标记该条数据“已删除”。


参考了一些网络上的讨论如下:

关于soft delete的好处,justjavac的介绍很棒。

不过是否应该使用soft delete,还是需要慎重考虑。

在关系型数据库中,软删除(soft delete)主要影响的是write的效率,而不是read,所以在这种情况下,考虑采用soft delete的可行性的时候,也要考虑你的table/database面对的是否是write intensive的需求。另外,采用soft delete,一般是为了可能的恢复,为了audit,为了保存历史数据等等目的。那么为了某个或者某些数据,是否soft delete真的是最好的处理方式呢?比如为了log的auditing,而对log采用soft delete,或许就有一些小题大做了。

而对于NoSQL数据库,软删除通常来讲是很容易接收的。尤其是Key-Value的NoSQL数据库,比如Amazon的Dynamo DB和Riak等等,实现原理是hash table,所以就算有大量的soft delete数据,也不会对性能造成巨大的影响。而对于其他类型的NoSQL数据库,Document-based(比如CouchDB)或者Column-based(比如hbase)等等,data integrity重要性也是远远超过采用soft delete带来的性能下降的。


小数据无所谓,看需求了
数据量大,最好另建一表保存删除数据
删除的很少用


根据需求而定,以后基本不用的数据完全可以删除(可以采取缓冲处理,先标记,后在系统不忙时删除)节省空间,减少无用检索;另一种情况,数据以后可能被重复利用,则打上标记,空闲时移到历史库。

关系数据库用来记录当前的客观事实,增、删、改,对应事实的改变。
有一种类型的表称为“history table”(或"audit table"),他们是专门用来记录历史数据的。通过trigger或存储过程实现。他们的功能跟其他表不同,他们记录的是对数据库的操作,不是业务范围的事实。history table通常数据量会随时间越来越大,它们没有删、改,只有增、查(少量的查),而current table中的数据量相对较小,正好满足业务需要(增、删、改、查)。


打标记好,万一是某人发布了敏感言论然后删除,那么警察叔叔查水表的难度肯定比用delete删除的难度小的多。


数据库设计原则–不要删除数据

摘自Segment的问题回复,个人认为是对数据库中删除操作最好的诠释,大部分情况下我们是滥用删除或删除标记,真实情况中大部分情况我们只需修改记录的状态即可。因此在做数据库设计中,我们决定使用删除或删除标记的时候,我们需要再思考一次:在业务上,这真的是删除操作吗?

Udi Dahan 强烈建议完全避免数据删除。

所谓软删除主张在表中增加一个 IsDeleted 列以保持数据完整。如果某一行设置了IsDeleted标志列,那么这一行就被认为是已删除的。Ayende 觉得这种方法“简单、容易理解、容易实现、容易沟通”,但“往往是错的”。问题在于:

删除一行或一个实体几乎总不是简单的事件。它不仅影响模型中的数据,还会影响模型的外观。所以我们才要有外键去确保不会出现“订单行”没有对应的父“订单”的情况。而这个例子只能算是最简单的情况。……

当采用软删除的时候,不管我们是否情愿,都很容易出现数据受损,比如谁都不在意的一个小调整,就可能使“客户”的“最新订单”指向一条已经软删除的订单。

如果开发者接到的要求就是从数据库中删除数据,要是不建议用软删除,那就只能硬删除了。为了保证数据一致性,开发者除了删除直接有关的数据行,还应该级联地删除相关数据。可Udi
Dahan提醒读者注意,真实的世界并不是级联的:

假设市场部决定从商品目录中删除一样商品,那是不是说所有包含了该商品的旧订单都要一并消失?再级联下去,这些订单对应的所有发票是不是也该删除?这么一步步删下去,我们公司的损益报表是不是应该重做了?

没天理了。

问题似乎出在对“删除”这词的解读上。Dahan 给出了这样的例子:

我说的“删除”其实是指这产品“停售”了。我们以后不再卖这种产品,清掉库存以后不再进货。以后顾客搜索商品或者翻阅目录的时候不会再看见这种商品,但管仓库的人暂时还得继续管理它们。“删除”是个贪方便的说法。

他接着举了一些站在用户角度的正确解读:

订单不是被删除的,是被“取消”的。订单取消得太晚,还会产生花费。
员工不是被删除的,是被“解雇”的(也可能是退休了)。还有相应的补偿金要处理。
职位不是被删除的,是被“填补”的(或者招聘申请被撤回)。

在上面这些例子中,我们的着眼点应该放在用户希望完成的任务上,而非发生在某个实体身上的技术动作。几乎在所有的情况下,需要考虑的实体总不止一个。

为了代替 IsDeleted 标志,Dahan 建议用一个代表相关数据状态的字段:有效、停用、取消、弃置等等。用户可以借助这样一个状态字段回顾过去的数据,作为决策的依据。

删除数据除了破坏数据一致性,还有其它负面的后果。Dahan建议把所有数据都留在数据库里:“别删除。就是别删除。”

—— 《NoSQL数据库笔谈》


数据库设计原则:应该使用软删除吗?相关推荐

  1. 数据库设计原则与开发规范,你知道多少?

    VOL 187 21 2020-12 今天距2021年11天 这是ITester软件测试小栈第187次推文 点击上方蓝字"ITester软件测试小栈"关注我,每周早上 08:30准 ...

  2. 数据库设计(二)——数据库设计原则

    一.数据库表的设计原则 1.不应该针对整个系统进行数据库设计,而应该根据系统架构中的组件划分,针对每个组件所处理的业务进行组件单元的数据库设计:不同组件间所对应的数据库表之间的关联应尽可能减少,如果不 ...

  3. 数据库设计原则和优化

    数据库设计原则: 1. 原始单据与实体之间的关系  可以是一对一.一对多.多对多的关系.在一般情况下,它们是一对一的关系:即一张原始单据对应且只对应一个实体.  在特殊情况下,它们可能是一对多或多对一 ...

  4. 规范化-数据库设计原则

    摘要 关系型数据库是当前广泛应用的数据库类型,关系数据库设计是对数据进行组织化和结构化的过程,核心问题是关系模型的设计.对于数据库规模较小的情况,我们可以比较轻松的处理数据库中的表结构.然而,随着项目 ...

  5. mysql数据库设计的原则_MySQL数据库设计原则

    转自 http://www.supidea.com/post/mysql_design_database.aspx MySQL数据库设计原则 MySQL对于成为一个非常快速的数据库服务器有着当之无愧的 ...

  6. MYSQL数据库设计原则

    一.MYSQL数据库设计原则 1.核心原则 不在数据库做运算; cpu计算务必移至业务层; 控制列数量(字段少而精,字段数建议在20以内); 平衡范式与冗余(效率优先:往往牺牲范式) 拒绝3B(拒绝大 ...

  7. 数据库-优化-MYSQL数据库设计原则

    MYSQL数据库设计原则 1.核心原则 不在数据库做运算; cpu计算务必移至业务层; 控制列数量(字段少而精,字段数建议在20以内); 平衡范式与冗余(效率优先:往往牺牲范式) 拒绝3B(拒绝大sq ...

  8. 数据库设计基本步骤 / 数据库设计原则

    基本步骤         按照规范设计的方法,同时考虑数据库及其应用系统开发的全过程,可以将数据库设计分为以下 6 个阶段: 需求分析阶段 需求分析是数据库设计的第一步,也是整个设计过程的基础,本阶段 ...

  9. 数据库设计原则和需要考虑的因素

    MYSQL数据库设计规范1.数据库命名规范采用26个英文字母(区分大小写)和0-9的自然数(经常不需要)加上下划线'_'组成;命名简洁明确(长度不能超过30个字符);例如:user, stat, lo ...

最新文章

  1. Vue.js slots: 为什么你需要它们?
  2. leangoo项目管理软件应用场景
  3. 自制奇葩vb面试题,看你能对几道
  4. dTree 动态生成树(http://luohua.iteye.com/blog/451453)
  5. 前端技术公众号运营心得记录
  6. ML.NET Cookbook:(4)如何调试实验或预览管道?
  7. 莓良心(第二类斯特林数)
  8. mysql跳过安全_Navicat连接MySQL数据库
  9. webpack的安装
  10. 操作系统概念:系统引导过程、引导程序、固件
  11. windows7安装cuda10.2
  12. 微信小程序引入iconfont图标
  13. Android 设置半透明颜色的效果
  14. 迎合老板还是员工 结果导向CRM更受欢迎
  15. 面试官问:为什么 Java 线程没有Running状态?我懵了
  16. java复习二十一天[多线程终]
  17. 互联网程序员普遍都是年薪百万嘛?
  18. 使用Windows驱动的虚拟打印机,打印Excel表格无表格线问题解决(1)
  19. break跳出两个嵌套的for循环
  20. java 在数组末尾添加元素和在任意位置删除元素

热门文章

  1. POJ - 3263 Tallest Cow(简单差分)
  2. centos php imap,centos 5.5 64 php 添加imap 模块记录
  3. antd 设置表头属性_解决react使用antd table组件固定表头后,表头和表体列不对齐以及配置fixed固定左右侧后行高度不对齐...
  4. python安装后无法运行任何软件_为啥我按照python安装教程,总说无法启动此程序,因为计算机中丢失?...
  5. UVa10410 Tree Reconstruction(bfs+dfs确定二叉树)
  6. 1961-Check If String Is a Prefix of Array(检查字符串是否为数组前缀)
  7. TypeScript 枚举指南
  8. 闻茂泉:系统性能监控与分析的工程化实践之路
  9. 一个 bad file descriptor 的问题
  10. 【跨Web与客户端多媒体开发】