Sqlite3/C++在不更改数据库大小的情况下执行DELETE语句

Sqlite3/C++ executes DELETE statement without changing the db size

本文关键字:情况下 执行 语句 DELETE 数据库 C++ Sqlite3      更新时间:2023-10-16

这怎么可能?我有一个简单的C++应用程序,它使用SQLite3来插入/删除记录。我在里面使用一个数据库和一个表。然后,在我选择将一些数据存储到数据库中后,它确实做到了,my.db的大小自然会增加。

虽然DELETE有问题,但事实并非如此。但如果我这样做:

sqlite3 my.db
sqlite> select count(*) from mytable;

返回了0,这是可以的,但如果在包含my.db的文件夹上执行ls -l,则大小是一样的。

有人能解释一下吗?

执行DELETE查询时,Sqlite实际上不会删除记录并重新排列数据。那将花费太多时间。相反,它只是标记已删除的记录,并从那时起忽略它们

如果您真的想减小数据大小,请执行VACUUM命令。还有一个自动吸尘的选项。看见http://www.sqlite.org/lang_vacuum.html.

SQLite常见问题解答:中列出了该场景

(12)我删除了很多数据,但数据库文件没有得到任何数据更小这是个虫子吗

没有。当您从SQLite数据库中删除信息时,未使用的磁盘空间将添加到内部"空闲列表"中并重复使用下次插入数据时。磁盘空间没有丢失。但两者都没有是否返回到操作系统。

如果删除了大量数据并希望收缩数据库文件,请运行VACUUM命令。VACUUM将从划痕这将使数据库保留一个空的空闲列表和一个最小大小的文件。但是,请注意,VACUUM可以运行一段时间(在Linux上每兆字节大约半秒SQLite是在哪里开发的),并且它可以使用两倍的临时磁盘空间作为运行时的原始文件。

从SQLite 3.1版起,使用VACUUM命令的另一种选择是使用auto_vacuum pragma启用的自动真空模式。

文档是您的朋友使用它。


同样来自文件:

当数据库中的信息被删除时,btree页面变成为空,它不会从数据库文件中删除,而是标记为作为"免费"以供将来使用。当需要新页面时,SQLite将使用在增加数据库大小之前的这些空闲页面之一。这导致数据库碎片,文件大小增加超出存储其数据和数据本身所需的大小文件变得杂乱无章。

动态数据库的另一个副作用是表碎片。这个包含单个表的数据的页面可能会分散通过数据库文件,需要更长的时间才能加载。这个可以由于文件系统的行为,数据库速度明显较慢。压实可以解决这两个问题。

删除空页的最简单方法是使用SQLite命令真空。这可以在SQLite库调用或sqlite实用程序。

下面是一些深入的例子。