如何在SQL Server 2005中实现高性能树视图

时间:2009-05-12 14:12:12

标签: sql sql-server database tree

构建代表树的表的最佳方法是什么? 我想实现一个适用于大数据的选择,插入,更新和删除。 例如,select必须支持“Expand ALL” - 获取给定节点的所有子节点(以及子节点)。

5 个答案:

答案 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

,此查询将返回idparent和深度级别,按树排序:

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。读取效率非常高,写入非常简单。