SQLite 数据库通常存储在一个普通的磁盘文件中。但是,在某些情况下,数据库可能会存储在内存中。
强制 SQLite 数据库完全存在于内存中最常见的方法是使用特殊文件名“:memory:”打开数据库。换句话说,而不是将真实磁盘文件的名称传递到 sqlite3_open()、sqlite3_open16() 或 sqlite3_open_v2() 函数中,而是传递字符串“:memory:” 。例如
rc = sqlite3_open(":memory:", &db);
这样做时,不会打开任何磁盘文件。相反,将在内存中创建一个新的数据库。一旦数据库连接关闭,数据库将不复存在。每个 :memory: 数据库都与其他数据库不同。因此,打开两个数据库连接,每个连接都使用文件名“:memory:” 将创建两个独立的内存数据库。
特殊文件名“:memory:” 可用于允许使用数据库文件名的任何位置。例如,它可以用作 ATTACH 命令中的 filename
ATTACH DATABASE ':memory:' AS aux1;
请注意,为了使特殊“:memory:” 名称生效并创建纯内存数据库,文件名中不能有任何其他文本。因此,可以通过添加路径名来在文件中创建基于磁盘的数据库,如下所示:"./:memory:”。
使用 URI 文件名 时,特殊“:memory:” 文件名也适用。例如
或者,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;
这允许单独的数据库连接共享同一个内存数据库。当然,所有共享内存数据库的数据库连接都需要在同一个进程中。当最后一个连接到数据库的连接关闭时,数据库将自动删除,内存将被回收。
如果在一个进程中需要两个或多个不同的但可共享的内存数据库,则可以使用 mode=memory 查询参数与 URI 文件名 一起创建命名内存数据库
或者,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 pragma 和 SQLITE_TEMP_STORE 编译时参数来强制临时数据库按需表现为纯内存数据库。