使用带有 QT4 QSQLDatabase 的 SQLite3 临时数据库

Use SQLite3 Temporary database with QT4 QSQLDatabase

http://www.sqlite.org/inmemorydb.html

提到创建临时数据库的能力,该数据库将存储在内存中,直到需要文件(如果有的话)。它还会在自动完成后删除该文件。这是通过提供一个空白数据库名称 "".

来实现的
rc = sqlite3_open("", &db);

我正在尝试使用 QSQLDatabase 在基于 QT4 的应用程序中执行此操作

QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("");
bool ok = db.open();

导致无法打开数据库。

我知道 :memory: 选项并且在我们的小型数据集应用程序中使用它要快得多。我更喜欢在必要时返回到文件的东西,因为我们可能有一些大数据集。

我假设允许数据库引擎在必要时缓存到文件比只让 OS 分页内存进出效率更高。

我愿意接受满足以下要求的替代方案:

更新 在阅读了一些建议的 SQLite 性能建议后,我现在在使用文件(事务!)时具有可接受的性能。

我还没有搞清楚如何使用 sqlite3 的内置临时文件功能。

我正在尝试使用 QTemporaryFile,但出于某种原因,它们不会按照文档暗示的方式自动删除。我还有一些实验要做。

TL;DR - NO,您不能使用 Qt 将空字符串作为数据库名称提供给 sqlite3。 (参见 编辑 3)。

原回答

一种可能性是将 backup option in SQLite 用于内存数据库。

但由于这听起来像是一个优化问题,您应该阅读 this SO answer which goes into a fair amount of detail about how you can speed up your database and disconnect it from the disk temporarily using PRAGMA synchronous = OFF and/or PRAGMA journal_mode = MEMORY. You might also want to limit the size of your in-memory pages by using the PRAGMA cache_size

编辑 1: 再次阅读您的问题后,我现在意识到您要求将 overflow 数据存储到磁盘并希望 SQLite只是管理,所以我的第一段没有用。

编辑 2: 添加了 PRAGMA cache_size 建议。

编辑 3: 回答问题的核心:

Your link to the other SO answer about SQLite optimization was very helpful, but still does not answer the meat of the question. ie how to use the sqlite3 built-in temp file functionality through the QT interface. Gavin S.

好的,但是答案是,原因如下。

如果您查看 Qt 源代码中的 SQLite 驱动程序,尤其是 QSQliteDriver::open 函数,它看起来像 this:

/*
   SQLite dbs have no user name, passwords, hosts or ports.
   just file names.
*/
bool QSQLiteDriver::open(const QString & db, const QString &, const QString &, const QString &, int, const QString &conOpts)
{
    if (isOpen())
        close();

->  if (db.isEmpty())
->      return false;
    bool sharedCache = false;
    int openMode = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, timeOut=5000;
    QStringList opts=QString(conOpts).remove(QLatin1Char(' ')).split(QLatin1Char(';'));
    foreach(const QString &option, opts) {
        if (option.startsWith(QLatin1String("QSQLITE_BUSY_TIMEOUT="))) {
            bool ok;
            int nt = option.mid(21).toInt(&ok);
            if (ok)
                timeOut = nt;
        }
        if (option == QLatin1String("QSQLITE_OPEN_READONLY"))
            openMode = SQLITE_OPEN_READONLY;
        if (option == QLatin1String("QSQLITE_ENABLE_SHARED_CACHE"))
            sharedCache = true;
    }

    sqlite3_enable_shared_cache(sharedCache);

->  if (sqlite3_open_v2(db.toUtf8().constData(), &d->access, openMode, NULL) == SQLITE_OK) {
        sqlite3_busy_timeout(d->access, timeOut);
        setOpen(true);
        setOpenError(false);
        return true;
    } else {
        setLastError(qMakeError(d->access, tr("Error opening database"),
                     QSqlError::ConnectionError));
        setOpenError(true);
        return false;
    }
}

The function sqlite3_open you are trying to call will never be called with an empty string as an argument because of the early return condition on lines 530 and 531 除非您在该特定代码行上修补 Qt 驱动程序。