【问题标题】:Create virtual table with rowid only of another table仅使用另一个表的 rowid 创建虚拟表
【发布时间】:2019-09-23 20:49:21
【问题描述】:

假设我在 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)。

【问题讨论】:

  • select rowid 而不是 select * ?
  • @GordonLinoff 因此,如果我按如下方式进行插入:CREATE TABLE vtable AS SELECT rowid from mytable ORDER BY name;,当我查询该表时如何获得完整的数据集?每次我进行查询时不需要加入 id 吗?
  • @GordonLinoff 刚刚用一个例子更新了这个问题。
  • 所以您想将表的有序子集保存到另一个表中?
  • 从您的上一条评论中可以清楚地看出您想要一个常规表格,并且由于您知道如何创建它,所以我不明白您的问题的重点。

标签: sql sqlite virtual-table


【解决方案1】:

我相信在创建 英尺。

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

虚拟表是可以调用模块的表,因此 USING 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) :-

【讨论】:

  • 我明白了,谢谢你的回答。看来我误解了 sqlite 中的虚拟表是什么。
猜你喜欢
  • 2019-06-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多