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

标签 c++ sqlite qt4

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

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

rc = sqlite3_open("", &db);

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

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

导致无法打开数据库。

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

我假设允许数据库引擎在必要时缓存到文件会比让操作系统分页内存更有效。

我愿意接受具有以下要求的替代方案:

  • 快速插入和查找
  • 申请结束后没有文件

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

我一直无法弄清楚如何使用 sqlite3 的内置临时文件功能。

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

最佳答案

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

原始答案

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

但由于这听起来像是一个优化问题,您应该阅读 this SO answer其中详细介绍了如何加速数据库并使用 PRAGMA synchronous = OFF 暂时断开它与磁盘的连接。和/或 PRAGMA journal_mode = MEMORY .您可能还想通过使用 PRAGMA cache_size 来限制内存页面的大小。 .

编辑 1: 再次阅读您的问题后,我现在意识到您要求将溢出数据存储到磁盘并希望 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由于 early return condition on lines 530 and 531,永远不会使用空字符串作为参数调用除非您在该特定代码行上修补 Qt 驱动程序。

关于c++ - 使用带有 QT4 QSQLDatabase 的 SQLite3 临时数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27931690/

相关文章:

c++ - 为什么C++ std::string 可以支持日语、法语的字符?

c++ - PThread - 尽管调用了 pthread_join,但线程提前退出

java - Android 中的 SQLITE 获取语句不起作用

opengl - cmake 不使用 QtOpenGL 链接 libGLU

C++,Qt 4 SQLite : can't create table

c++ - 以十六进制格式在缓冲区中插入一个值

c++ - 如何关闭使用 SHCreateStreamOnFile 打开的文件句柄

sqlite - 删除旧记录

sqlite - 在flutter中启动应用程序时,如何检查我的sqlflite数据库是否有数据?

c++ - 如何以编程方式更改布局中小部件的顺序?