4

我的应用程序目前使用 MySQL。为了支持非常快速的删除,我根据时间戳将数据组织在分区中。然后,当数据过时时,我只需删除整个分区。
它工作得很好,清理我的数据库不会损害我的应用程序性能。

我想用 MongoDB 替换 MySQL,我想知道 MongoDB 中是否有类似的东西,或者我只需要一个一个地删除记录(恐怕这会很慢并且会使我的数据库忙,并减慢查询响应时间)。

4

3 回答 3

10

在 MongoDB 中,如果您的要求是删除数据以限制集合大小,则应该使用capped collection

另一方面,如果您的要求是根据时间戳删除数据,那么TTL 索引可能正是您正在寻找的。

来自关于封顶收藏的官方文档:

Capped 集合会自动删除集合中最旧的文档,而无需脚本或显式删除操作。

关于 TTL 索引:

作为一种特殊的索引类型实现,TTL 集合可以将数据存储在 MongoDB 中,并让 mongod 在指定时间段后自动删除数据。

于 2013-05-16T13:38:18.140 回答
5

我想,即使我迟到并且答案已经被接受,我也会再补充一点。

上限集合的问题在于它们经常驻留在集群中的一个分片上。尽管在 MongoDB 的后期版本中,上限集合是可分片的,但它们通常不是。除此之外,必须在现场分配一个上限集合,因此如果您希望在清除数据之前拥有较长的历史记录,您可能会发现您的集合占用的空间比应有的要多得多。

TTL 是一个很好的答案,但它不如drop(). TTL 基本上是 MongoDB 在服务器端做同样的事情,你会在你的应用程序中做判断一行何时是历史记录并删除它。如果做得过多,将对性能产生不利影响。不仅如此,它也不擅长为你$freelist的 s 释放空间,这是阻止 MongoDB 中的碎片的关键。

drop()一个集合实际上只是当场“丢弃”集合,立即优雅地将该空间归还给 MongoDB(而不是操作系统),让您绝对不会有任何碎片。不仅如此,而且在 90% 的时间里,操作比大多数其他替代方案要快得多。

所以我会坚持我的评论:

您可以根据数据变为历史所需的时间将数据分解为时间序列集合,然后只需 drop() 集合

编辑

正如@Zaid 指出的那样,即使有_id字段上限的集合也不是可分片的。

于 2013-05-17T10:47:55.950 回答
0

一种解决方案是使用支持分区的 TokuMX: https ://www.percona.com/blog/2014/05/29/introducing-partitioned-collections-for-mongodb-applications/

与封顶集合相比的优势:封顶集合使用固定数量的空间(即使您没有这么多数据)并且它们不能即时调整大小。分区集合的使用取决于数据;您可以根据需要添加和删除分区(用于新插入的数据)。

与 TTL 相比的优势:TTL 很慢,它只负责自动删除旧数据。分区很快 - 删除数据基本上只是文件删除。

然而:在被 Percona 收购后,TokuMX 的开发似乎已经停止(希望在这一点上得到纠正)。不幸的是,MongoDB 不支持此功能,并且随着 TokuMX 的退出,如果没有适当的解决方案,我们将陷入困境。

于 2015-10-27T07:17:23.537 回答