SQLite 数据库通常存储在单个普通磁盘文件中。然而,在某些情况下,数据库可能会存储在内存中。
强制 SQLite 数据库完全存在于内存中的最常见方法是使用特殊文件名 “:memory:” 打开数据库。换句话说,不要将真实磁盘文件名传递给 sqlite3_open()、sqlite3_open16() 或 sqlite3_open_v2() 函数,而是传入字符串 ":memory:"
。例如:
rc = sqlite3_open(":memory:", &db);
此操作不会打开磁盘文件,而是纯粹在内存中创建新数据库。一旦数据库连接关闭,该数据库即不复存在。每个 :memory:
数据库彼此独立。因此,打开两个文件名均为 ":memory:"
的数据库连接将创建两个独立的内存数据库。
特殊文件名 ":memory:"
可用于允许使用数据库文件名的任何场景。例如,可用作 ATTACH 命令中的文件名:
ATTACH DATABASE ':memory:' AS aux1;
注意:要使特殊的 ":memory:"
名称生效并创建纯内存数据库,文件名中不得包含额外文本。因此,通过添加路径名(如 "./:memory:"
)可在文件中创建基于磁盘的数据库。
特殊文件名 ":memory:"
在使用 URI 文件名 时同样有效。例如:
rc = sqlite3_open("file::memory:", &db);
或者,
ATTACH DATABASE 'file::memory:' AS aux1;
内存数据库与共享缓存
如使用 URI 文件名 打开,内存数据库允许使用共享缓存。如使用未修饰的 ":memory:"
名称指定内存数据库,该数据库将始终具有私有缓存,且仅对最初打开它的数据库连接可见。但是,可通过以下方式由两个或多个数据库连接打开同一个内存数据库:
rc = sqlite3_open("file::memory:?cache=shared", &db);
或者,
ATTACH DATABASE 'file::memory:?cache=shared' AS aux1;
这使得不同的数据库连接可共享同一内存数据库。当然,所有共享该内存数据库的连接必须位于同一进程中。当最后一个数据库连接关闭时,数据库将自动删除且内存被回收。
如需在单个进程中创建两个或以上独立但可共享的内存数据库,可结合 URI 文件名 使用 mode=memory 查询参数创建命名内存数据库:
rc = sqlite3_open("file:memdb1?mode=memory&cache=shared", &db);
或者,
ATTACH DATABASE 'file:memdb1?mode=memory&cache=shared' AS aux1;
当内存数据库以这种方式命名时,仅与使用完全相同名称的其他连接共享其缓存。
临时数据库
当传递给 sqlite3_open() 或 ATTACH 的数据库文件名为空字符串时,将创建新的临时文件来存储数据库。
rc = sqlite3_open("", &db);
ATTACH DATABASE '' AS aux2;
每次都会创建不同的临时文件,因此与特殊的 ":memory:"
字符串类似,连接到临时数据库的两个数据库连接各自拥有私有数据库。临时数据库在创建它们的连接关闭时自动删除。
尽管为每个临时数据库分配了磁盘文件,但实际上临时数据库通常驻留在内存分页缓存中,因此 ":memory:"
创建的纯内存数据库与空文件名创建的临时数据库差异极小。唯一区别在于:":memory:"
数据库必须始终保留在内存中,而临时数据库的部分内容可能在数据库变大或 SQLite 面临内存压力时被写入磁盘。
以上段落描述了默认 SQLite 配置下临时数据库的行为。应用程序可根据需要使用 temp_store 编译指示 和 SQLITE_TEMP_STORE 编译时参数 强制临时数据库表现为纯内存数据库。