查询SQLite树结构

查询SQLite树结构,sqlite,tree,Sqlite,Tree,我有一个如下表的数据库: '00001000110002300042' 树{id,name,parent} content{id,content,parent} 树表包含一个类似树的结构,其中如果父元素为0,则它是顶级元素,如果它不同,则它是来自同一表的父元素的id content表有一个parent列,它是树表中的id 我想要的是,当为内容提供一个ID时,得到整个父子元素链 我不认为这是最好的表格结构,我想我可以改变这一点 请问您对此有何看法?首先,我建议使用parent=NULL而不是零来

我有一个如下表的数据库:

'00001000110002300042'
树{id,name,parent}
content{id,content,parent}

表包含一个类似树的结构,其中如果父元素为0,则它是顶级元素,如果它不同,则它是来自同一表的父元素的id

content
表有一个
parent
列,它是
表中的id

我想要的是,当为内容提供一个ID时,得到整个父子元素链

我不认为这是最好的表格结构,我想我可以改变这一点


请问您对此有何看法?

首先,我建议使用
parent=NULL
而不是零来表示根节点,这将允许
tree
parent
上有一个外键,它引用
id
;引用完整性很有用

然后,您可以在每一行中包含从根节点到当前节点的数据。具体化的路径将是一个字符串列,表示从根节点到当前节点的路径;出于您的目的,您可能希望对路径中的每个节点使用固定宽度的格式,然后您可以对路径进行逻辑排序,以按树的顺序(如下所示)拉出记录

假设您认为99999足以覆盖所有节点。然后您可能会有如下字符串路径:

'00001000110002300042'
这将表示ID序列
[1,11,23,42]
,因此节点的父节点是42,祖父母是23,依此类推,直到1的根节点。要获得从节点到根的整个分支:抓取路径,将其拆分为若干部分以获得ID,并在对具体化路径进行排序的同时立即拉出所有节点,以正确的顺序将它们取出

这种方法还可以很容易地一次提取整个子树:只需构建与所需子树匹配的路径前缀,然后按路径id执行类似“pfx%”的
路径,以一次性提取整个子树。此外,大多数数据库都会使用一个索引来表示一个从一开始就扎根的类似表达式(例如,对于某些
X
,类似于'X%'
),因此这类查询可以非常快速。您还可以通过简单的字符串长度和除法计算来计算节点的深度


您需要做一些额外的工作来构建物化路径,但不需要做太多,而且它们使许多树操作变得简单而漂亮,同时保持了树的自然表示的优点。

或者,您可以使用物化路径进行查询,尤其是在查询下,但写入速度较慢。如果树是动态的、写密集型的、轻读的并且没有那么深,那么简单id、父递归可能更好。它高度依赖于访问模式。但通常情况下,物化路径列是good@bryanmac:一切都取决于访问模式:)我通常使用PostgreSQL,因此使用数组和触发器实现的递归CTE或物化路径通常可以做到这一点。谢谢你,穆。[额外字符,因为它太短]如果树很深,则物化路径似乎也是一个糟糕的选择。@Michael如果树很深(而且很宽),则SQLite可能不是最好的数据存储。当然,任何方法都存在权衡。