在数据库中保留记录,而不是删除记录,以解决性能问题



所以我有一个客户端,我正在为它构建Rails应用程序。。。。我正在使用PostgreSQL。

他说他更喜欢隐藏记录,而不是删除记录。鉴于这是我第一次听说这件事,我想我会请你们听听你们的想法。

我宁愿隐藏也不愿删除,因为表中的删除最终会导致表索引破坏,导致查询花费的时间比预期的要长(比插入或更新更糟糕)。这在网站刚开始时不会是一个问题(随着时间的推移,情况会呈指数级恶化),但似乎是一个永远不会遇到的简单问题,因为作为"日常"web应用程序功能的一部分,没有删除任何内容。作为数据优化&维护过程,并在该过程中按计划(待定)重新索引表。

在我构建的所有Rails应用程序中,我从未遇到过删除记录和影响索引的问题。

我是不是错过了什么?这是以前存在的问题,但现代RDBMS产品已经解决了吗?

选择不删除记录可能有功能上的原因,但除非有一些技术证据支持,否则与某种形式的表索引"浩劫"有关的原因几乎肯定是假的。

在Oracle世界中,您经常听到这样的事情——索引不会重用删除所释放的空间。这通常是基于对事实的误解(例如,索引块在完全空之前不会被释放以供重用)。因此,最终会有人提出定期重建索引的建议。如果你考虑一下这些问题,你会想知道为什么RDBMS开发人员不会解决这样的问题,因为它可能会损害系统性能。

因此,这可能是基于一些与Postgres相关的、可能过时的信息,但反对完全正常类型的数据库操作的人确实有责任提供证据来支持他们的立场。

另一个想法是:我相信在Postgres中,更新是以删除和插入的方式实现的,因此建议经常清空更新严重的表。基于此,更新还应该导致与删除相关联的相同索引问题。

不删除记录的其他原因。

  1. 您不必担心通过数据库中引用您正在删除的行的各种其他表级联删除

  2. 每一点数据都是有用的。调试和审核变得很容易。

  3. 如果需要,更容易回滚。

在表中创建一个已删除的列,并不对该列进行索引。

如果用deleted=1或deleted=o更新该记录,则只需要重写数据,无需更新索引即可节省大量IO读取和IO写入

这一建议适用于所有使用B树索引的现代RDBMS。B树是一个很好的搜索算法,但不适合更新和删除,因为在节点中插入或更新节点或从树中删除注释需要大量的IO读取和IO写入,这也是为什么你不应该"过度索引"你的表的原因

"删除"类似的记录

UPDATE table SET deleted = 1 WHERE id = 1 -- if deleted not is indexed assuming id is index as an primary key this also should be fast

检查记录是否已删除

SELECT * FROM table WHERE id = 1 and deleted = 1 -- assuming id is index as an primary key this also should be fast

检查是否删除了未删除的记录

SELECT * FROM table WHERE id = 1 and deleted = 0 -- assuming id is index as an primary key this also should be fast

最新更新