将 SQLite3 临时数据库与 QT4 QSQLDatabase 一起使用
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:
选项,在我们的应用程序中将其用于小型数据集的速度要快得多。我更喜欢在必要时回落到文件的东西,因为我们可能有一些大型数据集。
我假设允许数据库引擎在必要时缓存到文件比仅让操作系统对内存进行分页更有效。
我愿意接受具有以下要求的替代方案:
- 快速插入和查找
- 应用程序关闭后没有文件
更新在浏览了一些建议的SQLite性能建议之后,我现在在使用文件(事务!
我一直无法弄清楚如何使用sqlite3的内置临时文件功能。
我正在尝试使用 QTemporaryFile,但由于某种原因,它们不会像文档暗示的那样自动删除它们应该删除的方式。我还有一些实验要做。
TL;DR - 不,您不能使用 Qt 为 sqlite3 提供空字符串作为数据库名称(请参阅编辑 3)。
原答案
一种可能性是将 SQLite 中的备份选项用于内存数据库。
但是由于这听起来像是一个优化问题,您应该阅读这个 SO 答案,其中详细介绍了如何加快数据库速度并使用 PRAGMA synchronous = OFF
和/或 PRAGMA journal_mode = MEMORY
暂时将其与磁盘断开连接。您可能还希望通过使用 PRAGMA cache_size
来限制内存中页面的大小。
编辑1:再次阅读您的问题后,我现在意识到您要求将溢出数据存储到磁盘,并希望SQLite仅对其进行管理,因此我的第一段没有用。
编辑 2:添加了PRAGMA cache_size
建议。
编辑3:回答问题的实质:
您链接到有关SQLite优化的其他SO答案非常有帮助,但仍然没有回答问题的实质。 即如何通过QT接口使用SQLite3内置的临时文件功能。加文·
好的,但答案是否定的,原因如下。
如果你看看Qt源代码中的SQLite驱动程序,特别是QSQliteDriver::open
函数,它看起来像这样:
/*
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;
}
}
您尝试调用sqlite3_open
函数永远不会使用空字符串作为参数进行调用,因为第 530 行和第 531 行的早期返回条件,除非您在该特定代码行上修补 Qt 驱动程序。
- 如何将enable-if与模板参数和参数包一起使用
- 如何将PERF_AMPLE_READ与mmap一起使用
- 如何将两个不同矢量的同一位置的两个元素组合在一起
- 如何将C++中的库和头与MinGW一起使用
- 将--whole archive链接器选项与CMake和具有其他库依赖项的库一起使用
- 为什么我不能将 rand() 与数组的大小一起使用?
- 要与"if constexpr"一起使用的编译时消息(在预处理器之后)
- 不能将复制初始化与隐式转换的多个步骤一起使用
- 将fold表达式与std::一起用于两个元组
- spdlog标头仅与外部fmt一起使用.spdlog错误:'内部':不是'fmt'
- 将 std::allocate_shared 与多态资源分配器一起使用
- 为什么常量词在重载运算符中不与 ostream 对象一起使用<<?
- 将 OpenCV 与 CMAKE 中的项目一起构建为第三方库的正确方法
- 将 exprtk 与自定义类的对象一起使用
- 将 std::set 与基于键的比较器一起使用
- 将 C++ 类与 Rcpp 一起使用,从 C 或 R 修改它
- 如何将 Eigen::Ref 与 pybind11 一起使用?
- 将 SQLite3 临时数据库与 QT4 QSQLDatabase 一起使用
- 将Qt与eclipse一起使用,#include <QSqlDatabase> 会导致找不到文件
- 是否可以将QSqlDatabase与SQLCipher一起使用?