仅使用另一个表的行ID创建虚拟表

时间:2019-09-23 20:49:21

标签: sql sqlite virtual-table

假设我在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索引-{{3}时,这被称为外部内容}。

1 个答案:

答案 0 :(得分:2)

  

我认为在创建广告系列时,这称为外部内容   英尺。

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

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

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

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

您很可能不需要/想要虚拟表。


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;

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

然后,您将获得3个快照(每个快照具有许多行,但每个快照的id列中的值相同),第一个具有2行,第二个具有4行,最后一个具有6行(每次运行2行)正在添加到mytable中):-

enter image description here

相关问题