使用另一个 table 的 rowid 创建虚拟 table

Create virtual table with rowid only of another table

假设我在sqlite中有一个table如下:

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

我想使用最少的存储 space 来存储以下 table 的结果:

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

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

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

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

然后我相信每次我需要查询 vtable 时,我都必须使用 rowid 将它连接回原来的 table。有没有办法做到这一点,以便 vtable "knows" 它基于外部 table 的内容(我相信这在创建 fts索引--https://sqlite.org/fts5.html#external_content_tables).

I believe this is referred to as external-content when creating an fts.

没有使用 CREATE VIRTUAL TABLE ...... USING module_name (module_parameters)

创建虚拟 table

虚拟table是可以调用模块的table,因此必须使用USING module_name(module_parameters)。

对于 FTS(全文搜索),您必须阅读 documentation 但它可能类似于

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

您很可能不会 need/want 虚拟 table。


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

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

我建议对所有具有两列的快照使用单个 table,快照标识符和快照的 rowid。这可能会少得多 space 消耗。

基本示例

考虑一下:-

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;

以上是运行3次,间隔合理(以秒为单位,以区分快照id(时间戳))。

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