3

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

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

我宁愿隐藏而不是删除,因为表中的删除最终会导致表索引破坏,导致查询花费的时间比预期的要长(比插入或更新差得多)。这在网站开始时不会成为问题(随着时间的推移它会呈指数级恶化),但作为“日常”Web 应用程序功能的一部分,只是不删除任何内容(尚未),这似乎是一个永远不会遇到的简单问题。作为数据优化和维护过程的一部分,我们总是可以稍后处理删除,并在某些(尚未确定)计划的基础上在该过程中重新索引表。

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

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

4

3 回答 3

1

倾向于不删除记录可能有功能上的原因,但与某种形式的表索引“破坏”相关的原因几乎可以肯定是虚假的,除非有一些技术证据支持。

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

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

另一个想法:我相信在 Postgres 中,更新是作为删除和插入实现的,因此建议在频繁更新的表上进行清理。基于此,更新也应该导致与删除相关的相同索引问题。

于 2013-08-31T13:10:06.680 回答
1

不删除记录的其他原因。

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

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

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

于 2013-08-31T03:16:55.627 回答
0

在您的表中创建一个已删除的列,并且不要索引该列。

如果您使用 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
于 2013-08-31T12:56:06.490 回答