我应该删除或禁用关系数据库中的行吗?

dan*_*ine 27 mysql sql oracle relational

在一个全新的程序中,空间并不是真的那么大,最好是删除行或禁用行,让我们说一个布尔"禁用"并让程序忽略它?

例如,如果我想从程序中删除用户.

dkr*_*etz 22

这取决于.(但你已经猜到了,我确定.)

在实践中,这里违反正确使用几乎总是朝着删除的方向.

删除的主要不良后果是在父记录消失时,其他表中依赖记录的参与完整性丢失的频率.

用于防御删除的一个红鲱鱼(你已经通过解除存储容量问题已经妥善处理了),期望它会在查询效率方面产生任何明显的差异.

有太多用户或软件问题导致某人需要点击"撤消"按钮的情况; 如果你删除,你运气不好(至少没有得到特别的帮助,加重了你宁愿做的人.)

我通常使用的术语是"活动"和"非活动".


还需要考虑几点(Totophil):

  1. 删除某些数据库中的记录不会自动释放磁盘空间.
  2. 清除不再需要的任何敏感信息有助于避免安全风险.
  3. 数据保护立法可能要求您的组织在某些情况下清除有关个人的任何可识别信息.立法因国家而异,有些指示:

  4. 另一方面,法律可能要求您保留某些信息.


Mat*_*tin 22

不删除将为将来的所有查询创建新的错误类.不要忘记,查询编写通常由高级用户(即非IT专业人员)和初级开发人员完成.因此,现在每个具有仅由BIT活动标志标记的无效数据的表将在WHERE子句中为从现在起到永远的每个查询都需要一个额外的AND.这将有助于用户陷入失败的困境而不是成功的陷阱.但是,我强烈建议您无论如何都要实现这些标记系统,因为没有糟糕的设计,维护开发人员无需修复它将创建的众多错误.

表中的历史数据有多大价值?如果业务如果向前看,在表中包含旧数据可能只是一个负担 - 它在创建约束时会导致问题(必须修改所有约束以排除您希望的数据不存在).数据质量保证变得复杂,因为必须不断重新识别什么是"我们害怕删除但又不想再次使用或更新"的旧垃圾以及我们关心的新内容.

它被删除是因为这是一个错误吗?如果行对应于现实生活中的实体,那么保持并设置"蒸发","死","离开建筑物"标志可能是有趣的.如果您不小心插入了与现实生活中没有实体相对应的行,则DELETE不是一件坏事.从未存在的想象客户是否很重要,以保留在客户表中?

最后,个性扮演着重要角色.人们也可以对数据进行打包.如果DBA将所有报纸保存在30年前并且不喜欢删除数据,那么他应该确保他根据优点而不是无关的个人偏好做出数据设计决策.

  • 如果高级用户开发查询存在潜在问题,可以在表格周围创建一个自动过滤掉"已删除"行的视图.我认为,几乎不是一个小问题. (5认同)

rme*_*dor 17

在阅读了关于时态数据库设计的书之后,我开始相信这样一种理念,即每个时间重要性记录都需要至少有4个时间戳列.这四个是:创建,删除,开始,结束.创建和删除的时间戳相当不言自明.您的系统不应该查看之前删除的记录().开始和结束列确定数据何时适用于您的系统.这是为了保持变化的历史.如果需要更新记录,则将其结束时间设置为now(),复制,更新副本,并将副本的开始时间设置为now().这样,当您需要查看历史上的某种方式时,您可以让系统弄明白.您也可以将开始设置为将来的某个点,以便在此时自动进行更改,或者将结束设置为将来的时间让它自动消失.将创建/删除的时间戳设置为未来并没有多大意义......

  • 我总是发现将这种历史数据放在一个单独的数据仓库中会更好.所有这些历史数据都会使大型表格变慢.此外,如果您在表上执行大量插入操作,则数据库需要保持移位数据以保持聚簇索引的有序性. (2认同)

Ber*_*ert 17

如果您确实使用了已删除,可见,非活动等列,则可以抽象使用视图来记住使用它.


Dus*_*tin 6

这取决于你和你的要求(当记录存在时,某些事情变得相当困难......不要).

不过,我会说布尔值是一个糟糕的选择.使其成为可以为空的时间戳.知道何时删除某些内容非常方便,特别是当您删除太多并想要撤消部分删除时.


Dra*_*mon 0

这是一个判断调用,但我最终在我之前认为可以删除行的表上添加了“禁用”列。我想说大多数时候添加禁用列会更安全。然而,对于 n:n 关系来说,这可能会变得棘手,所以这是需要考虑的事情。