sql - 如何有效地将 SQlite 数据库缩小到给定的文件大小?

标签 sql windows sqlite

我在 Windows 上使用 SQLite 3.7.2。我的数据库用于存储 24/7 全天候生成的日志数据。架构基本上是:

CREATE TABLE log_message(id INTEGER PRIMARY KEY AUTOINCREMENT, process_id INTEGER, text TEXT);
CREATE TABLE process(id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT);

log_message.process_id 字段映射到 process.id,从而将每条日志消息与其来源的进程相关联。

现在,迟早数据库会变得太大,我想删除最旧的条目(那些具有最低 log_message.id 值的条目),直到数据库再次下降到给定大小(比如,1GB)。为此,我目前正在做

PRAGMA page_count;
PRAGMA page_size;

在每隔几条日志消息后获取数据库的大小。如果它超出了我的限制,我只删除一部分日志消息(现在:100 条消息),如下所示:

BEGIN TRANSACTION;
DELETE FROM log_message WHERE id IN (SELECT id FROM log_message LIMIT 100);
DELETE FROM process WHERE id IN (SELECT id FROM PROCESS EXCEPT SELECT process_id FROM log_message);
COMMIT;
VACUUM;

后面的 DELETE 语句从 process 表中删除所有未引用的条目。我重复此过程,直到文件大小再次可接受。

这至少有两个问题:

  1. 删除 100 条日志消息的方法非常随机;我根据一些实验得出了这个数字。我想知道我必须提前删除的条目数。
  2. 重复的 VACUUM 调用可能会占用相当长的时间(SQLite 主页说 VACUUM 在 Linux 上每 MB 最多可能需要半秒,我猜它在 Windows 上不会更快)。

有人对如何执行此操作有其他建议吗?

最佳答案

当你有一个“大小合适”的数据库时,然后计算 log_message 行的数量。

SELECT COUNT(*) FROM LOG_MESSAGE

存储这个数字。

当你想缩小文件时再次发出计数命令。计算差异,从数据库中删除该行数,然后 VACCUM。

这只能是近似值,但它会让您很快达到接近 1GB。如果您还没有结束,您可以回到一次 100 行的方法。

关于sql - 如何有效地将 SQlite 数据库缩小到给定的文件大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5987042/

相关文章:

SQL Server 2008 分区表和并行性

sql - 简单的 postgresql 插入/更新查询需要*秒*每 5-7 分钟响应一次

c++ - 数据未插入 sqlite 表 c++

mysql - 如何同步Core Data关系?

mysql - 查询获取数据,按两列分组,并按Client ID在一行中显示多个相似行

android - 推送通知的设备 token

c++ - 等待 COM 端口上的数据?

java - 如何让 Vista 的讲述人将我的 Swing 组件读回给我?

python - 使用 IN 运算符正确参数化 SQLite 查询

mysql - 获取累计计数