我有一个像这样的表数据库:
tree{id,name,parent}
content{id,content,parent}
tree
表包含一个树状结构,如果parent为0,则它是顶级元素,如果它不同,则它是来自同一个表的父级的id。
content
表格中有parent
列,该列是tree
表的ID。
我想要的是在给出内容ID时获得整个父子元素链。
我不认为这是表格的最佳结构,我想我可以改变它。
请问您对此有何看法?
答案 0 :(得分:4)
首先,我建议使用parent = NULL
而不是零来表示根节点,这将允许tree
在parent
上具有引用{{1}的外键}};引用完整性很有用。
然后,您可以在根节点中包含materialized path到每行的当前节点。物化路径将是一个字符串列,表示从根节点到当前节点的路径;为了您的目的,您希望对路径中的每个节点使用固定宽度格式,然后您可以对路径进行ASCII排序,以按树顺序提取记录(如此answer)。
假设您认为99999足以覆盖您的所有节点。那么你可能有这样的字符串路径:
id
那将代表ID序列'00001000110002300042'
,因此节点的父级将是42,祖父级23,依此类推,直到1的根。要从节点到根节点获取整个分支:抓住路径,将其拆分为多个部分以获取ID,并在物化路径上排序时立即拉出所有节点,以便按正确的顺序将它们输出。
这种方法还可以轻松地一次性提取整个子树:只需构建与所需子树匹配的路径前缀,然后执行[1, 11, 23, 42]
以一次性提取整个子树。此外,大多数数据库将使用一个索引作为一个以开头为根的LIKE表达式(即某些path LIKE 'pfx%' ORDER BY path, id
的{{1}}),因此这些类型的查询可以非常快。您还可以使用简单的字符串长度和除法计算来计算节点的深度。
你需要做一些额外的工作来构建物化路径但不是很多,它们使很多树操作变得简单而简单,同时保持了树的自然表示的优点。
答案 1 :(得分:0)