从影子表到原始表的 SQLite Rtree 映射 id(s)

Posted

技术标签:

【中文标题】从影子表到原始表的 SQLite Rtree 映射 id(s)【英文标题】:SQLite Rtree Mapping id(s) from Shadow table to Original table 【发布时间】:2017-04-09 20:53:18 【问题描述】:

我使用 SQLite 创建了一个 Rtree 数据结构,它生成 4 个表(一个用于原始表,三个影子表)。我试图弄清楚如何使用影子表中的 nodeno 属性检索原始表中一行的 id

根据 SQLite 文档,%rowid 表可用于将 id 从影子表映射到原始表。以下是文档说明的内容

"单个虚拟r树表的数据结构存储在三个 本机 SQLite 表声明如下。在每种情况下,'%' 字符 表中的名称被替换为用户提供的 r-tree 名称 表。

CREATE TABLE %_node(nodeno INTEGER PRIMARY KEY, data BLOB)

CREATE TABLE %_parent(nodeno INTEGER PRIMARY KEY, parentnode INTEGER)

CREATE TABLE %_rowid(rowid INTEGER PRIMARY KEY, nodeno INTEGER)

r-tree 结构的每个节点的数据都存储在 %_node 表中。对于每个不是 r-tree 根节点的节点,有 %_parent 表中的一个条目,将节点与其父节点相关联。 并且对于表中的每一行数据,%_rowid 中都有一个条目 从条目 rowid 映射到它的节点的 id 的表 存储在上面。”

我已尝试运行以下查询

SELECT p.id 
FROM mytable_rowid r, mytable p 
WHERE r.rowid = p.id  
AND r.nodeno = 9341;

我原以为该查询会返回原始表 (mytable) 中单个节点的 id,该节点在影子表的 nodeno 属性中的值为 9341,但它取而代之的是检索到原始表中的几行。

【问题讨论】:

【参考方案1】:

一个节点可以(必须,除非它是根节点)存储多行。

节点是树的边界框,不是吗?

参见 R-tree 论文,它有一个参数。

【讨论】:

是的,但是nodeno = 9341是rtree中的一个叶子节点 这也适用于叶节点。没有理由将每个数据点包装到一个单独的叶节点中,是吗?【参考方案2】:

source code 说:

    如果节点是根节点(节点 1),则节点的前 2 个字节包含作为大端整数的树深度。对于非根节点,前 2 个字节未使用。 接下来的 2 个字节包含当前存储在节点中的条目数。 节点的其余部分包含节点条目。每个条目由一个 8 字节整数和后跟偶数个 4 字节坐标组成。对于叶节点,整数是记录的 rowid。对于内部节点,它是子页面的节点号。

因此您无需查看_rowid 表;您可以直接从叶节点中的条目中获取它(如果您知道要哪个条目)。

(你不能search in the R-tree不查看所有节点的条目。)

【讨论】:

以上是关于从影子表到原始表的 SQLite Rtree 映射 id(s)的主要内容,如果未能解决你的问题,请参考以下文章

查询从内存映射文件中检索的 Rtree 时出现分段错误

使用 rtree 和普通索引的 SQLite 查询很慢

从一个维度表到单个事实表的多个连接

从 AWS Glue 表到 RedShift Spectrum 外部表的日期字段转换

存储过程中从一个表到另一个表的 Netezza 更新错误

如何在 EF 中创建从两个表到一个源的一对一映射?