0

假设我在 sqlite 中有一个表,如下所示:

`name`     `age`
"bob"      20      (rowid=1)
"tom"      30      (rowid=2)      
"alice"    19      (rowid=3)

我想使用最小的存储空间来存储下表的结果:

SELECT * FROM mytable WHERE name < 'm' ORDER BY age

如何从这个结果集中存储一个虚拟表,它只会给我有序的结果集。换句话说,以有序的方式存储rowid(在上面它会是3,1)而不将所有数据保存到单独的表中。

例如,如果我以排序顺序仅使用 rowid 存储此信息:

CREATE TABLE vtable AS 
SELECT rowid from mytable WHERE name < 'm' ORDER BY age;

然后我相信每次我需要查询时,vtable我都必须使用rowid. 有没有办法做到这一点,以便 vtable “知道”它基于外部表的内容(我相信在创建fts索引时这被称为外部内容 - https://sqlite.org/fts5 .html#external_content_tables)。

4

1 回答 1

2

我相信这在创建 fts 时被称为外部内容。

没有使用创建虚拟表CREATE VIRTUAL TABLE ...... USING module_name (module_parameters)

虚拟表是可以调用模块的表,因此 USING module_name(module_parameters) 是强制性的。

对于 FTS (Full Text Serach),您必须阅读文档,但可能类似于

CREATE VIRTUAL TABLE IF NOT EXISTS bible_fts USING FTS3(book, chapter INTEGER, verse INTEGER, content TEXT)

您很可能不需要/想要 VIRTUAL 表。


CREATE TABLE vtable AS SELECT rowid from mytable WHERE name < 'm' ORDER BY age;

如果它尚不存在,将创建一个正常的表,它将持续存在。如果你想使用它,那么它可能只有通过将它与 mytable 连接才能使用。实际上,它将允许一个快照,但代价是每个快照至少 4k。

我建议为所有快照使用一个表,该表具有两列快照标识符和快照的 rowid。这可能会占用更少的空间。

基本示例

考虑 :-

CREATE TABLE IF NOT EXISTS mytable (
    id INTEGER PRIMARY KEY, /* NOTE not using an alias of the rowid may present issues as the id's can change */
    name TEXT,
    age INTEGER
);
CREATE TABLE IF NOT EXISTS snapshot (id TEXT DEFAULT CURRENT_TIMESTAMP, mytable_map);

INSERT INTO mytable (name,age) VALUES('Mary',21),('George',22);

INSERT INTO snapshot (mytable_map) SELECT id FROM mytable;

SELECT snapshot.id,name,age FROM snapshot JOIN mytable ON mytable.id = snapshot.mytable_map;

以上以合理的间隔(秒,以便区分快照ID(时间戳))运行3次。

然后你会得到 3 个快照(每个快照都有许多行,但每个快照的 id 列中的值相同),第一个有 2 行,第二个有 4 行,最后一个有 6 个(因为每次运行 2 行被添加到 mytable) :-

在此处输入图像描述

于 2019-09-23T21:43:32.263 回答