将sqlite数据库从内存同步到文件

10
我正在编写一个应用程序,需要频繁记录信息,比如每秒两次。我想将信息保存到sqlite数据库中,但是我不介意每十分钟才将更改提交到磁盘。
在使用文件数据库时执行查询太耗时,会让电脑卡顿。
一种可选的解决方案是使用内存数据库(它能放下,不用担心),并且定期将其同步到磁盘上,
这是否可能? 有没有更好的方法来实现这一点(可以告诉sqlite只在X个查询后提交到磁盘)?
我能否使用Qt的SQL包装器来解决这个问题?

为什么不使用Ramdisk,然后每x秒钟将其简单地复制回来并在拆卸时处理呢?在我看来,处理文件比处理查询要好得多。即使数据库失败,也可以检索Ramdisk文件。它只是一个文件。 - m3nda
3个回答

16

假设您有一个名为“disk_logs”的磁盘数据库,并且其中有一个名为“events”的表。您可以将一个内存数据库连接到现有的数据库:

ATTACH DATABASE ':memory:' AS mem_logs;
在该数据库中创建一个表(完全是内存中的),用于接收传入的日志事件:
CREATE TABLE mem_logs.events(a, b, c);

然后在应用程序停机期间将内存表中的数据传输到磁盘表中:

INSERT INTO disk_logs.events SELECT * FROM mem_logs.events;

然后删除现有内存表的内容。重复此操作。

但是这相当复杂...如果您的记录跨越多个表并且使用外键链接在一起,将这些记录从内存表复制到磁盘表并保持同步可能会很麻烦。

在尝试像这样(过于过度工程)的操作之前,我还建议尽力使SQLite尽可能快。SQLite应该可以轻松处理每秒钟> 50K条记录的插入。每秒两次日志条目不应导致显着减速。


5
如果你在每个插入操作中执行单独的事务,那可能是导致你看到的缓慢的重要原因。也许你可以这样做:
  • 计算已插入记录的数量
  • 开始一个事务
  • 插入你的记录
  • 增加计数器
  • 当插入N条记录时提交/结束事务
  • 重复以上步骤
缺点是,如果系统在此期间崩溃,你有失去未提交记录的风险(但如果你愿意使用内存数据库,那么似乎你可以接受这种风险)。

2

在SQLite文档的简短搜索中没有找到有用的信息(这不太可能,我也没指望)。

为什么不使用后台线程,每10分钟唤醒一次,将内存数据库中的所有日志行复制到外部数据库中(并从内存数据库中删除它们)。当程序准备结束时,最后一次唤醒后台线程保存最后的日志,然后关闭所有连接。


因为那样我需要创建日志,记住我已经保存的日志的哪一部分,维护后台线程,并且在很大程度上自己实现同步。虽然这是可能的,但我想避免那样做。 - Elazar Leibovich

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接