构建代表树的表的最佳方法是什么? 我想实现一个适用于大数据的选择,插入,更新和删除。 例如,select必须支持“Expand ALL” - 获取给定节点的所有子节点(以及子节点)。
答案 0 :(得分:8)
使用CTE
。
给定树状表结构:
id parent name
1 0 Electronics
2 1 TV
3 1 Hi-Fi
4 2 LCD
5 2 Plasma
6 3 Amplifiers
7 3 Speakers
,此查询将返回id
,parent
和深度级别,按树排序:
WITH v (id, parent, level) AS
(
SELECT id, parent, 1
FROM table
WHERE parent = 0
UNION ALL
SELECT id, parent, v.level + 1
FROM v
JOIN table t
ON t.parent = v.id
)
SELECT *
FROM v
id parent name
1 0 Electronics
2 1 TV
4 2 LCD
5 2 Plasma
3 1 Hi-Fi
6 3 Amplifiers
7 3 Speakers
将parent = 0
替换为parent = @parent
以仅获取树的一个分支。
如果table (parent)
上有索引,此查询将有效地处理非常大的表,因为它将递归使用INDEX LOOKUP
来查找每个父项的所有chilrden。
要更新某个分支,请发出:
WITH v (id, parent, level) AS
(
SELECT id, parent, 1
FROM table
WHERE parent = 0
UNION ALL
SELECT id, parent, v.level + 1
FROM v
JOIN table t
ON t.parent = v.id
)
UPDATE table t
SET column = newvalue
WHERE t.id IN
(
SELECT id
FROM v
)
其中@parent
是分支的根。
答案 1 :(得分:3)
你必须首先问自己这些问题: 1)修改与读取的比例是多少? (=主要是静态树或不断变化?) 2)你对树的生长有多深和多大?
嵌套集适用于大多数静态树,您需要在整个分支上进行操作。它可以毫无问题地处理深树。
物化路径适用于具有约束/可预测深度的动态(变化)树。
递归CTE非常适合非常小的树,但是分支操作(“让所有孩子都进入这个分支......”)会因为深/大树而变得非常昂贵。
答案 2 :(得分:2)
查看Joe Celko's book on trees and hierarchies以了解解决层次结构问题的多种方法。您选择的模型将取决于您如何权衡查找与更新与复杂性的比重。您可以使用邻接列表模型使查找速度非常快(特别是在节点中获取所有子节点),但对树的更新速度较慢。
答案 3 :(得分:1)
如果你有很多更新和选择,最好的选择似乎是路径枚举模型,这里简要描述:
http://www.sqlteam.com/article/more-trees-hierarchies-in-sql
答案 4 :(得分:0)
我很惊讶没有人提到过Closure Table。读取效率非常高,写入非常简单。