php / Mysql最佳树形结构

时间:2011-05-06 20:07:56

标签: php mysql tree hierarchical-data hierarchical

我必须构建一个包含大约300个节点的树。树没有深度限制。所以它可以有3或15个级别。每个节点可以拥有无​​限数量的孩子。

优先级是尽可能快地获得完整的树/子树,但我还需要有时添加节点或移动节点,但不是经常这样。

我想知道在数据库中存储树的最佳方法,以及在php中检索数据的最佳方法。

3 个答案:

答案 0 :(得分:71)

您可以使用嵌套集模型,因为它可以产生非常高效的查询。查看Managing Hierarchical Data in MySQL并阅读名为嵌套集模型的部分。

如果您正在使用像Doctrine这样的ORM,那么includes nested set capabilities

有些人很难掌握 left 的嵌套集合概念。我发现使用这些数字作为开放行号的类比在XML文档中关闭标签,人们会发现它更容易掌握。

例如,从上面的MySQL链接获取数据示例:

+-------------+----------------------+-----+-----+
| category_id | name                 | lft | rgt |
+-------------+----------------------+-----+-----+
|           1 | ELECTRONICS          |   1 |  20 |
|           2 | TELEVISIONS          |   2 |   9 |
|           3 | TUBE                 |   3 |   4 |
|           4 | LCD                  |   5 |   6 |
|           5 | PLASMA               |   7 |   8 |
|           6 | PORTABLE ELECTRONICS |  10 |  19 |
|           7 | MP3 PLAYERS          |  11 |  14 |
|           8 | FLASH                |  12 |  13 |
|           9 | CD PLAYERS           |  15 |  16 |
|          10 | 2 WAY RADIOS         |  17 |  18 |
+-------------+----------------------+-----+-----+

如果您使用 lft rgt 字段并将其用作XML文档的行号,您将获得:

1. <electronics>
2.    <televisions>
3.        <tube>
4.        </tube>
5.        <lcd>
6.        </lcd>
7.        <plasma>  
8.        </plasma> 
9.     </televisions>
10.    <portable electronics>
11.        <mp3 players>
12.            <flash>
13.            </flash>
14.        </mp3 players>
15.        <cd players>
16.        </cd players>
17.        <2 way radios>
18.        </2 way radios>
19.    </portable electronics>
20. </electronics>

以这种方式查看可以使某些人更容易可视化生成的嵌套集层次结构。它还更清楚地说明了为什么这种方法可以提高效率,因为它可以选择整个节点而无需多个查询或连接。

答案 1 :(得分:7)

这是一篇很棒的文章:Managing Hierarchical Data in MySQL。我用了很长时间。

如果你有一些数学能力,你可以真正理解它为何如此伟大!

答案 2 :(得分:0)

def method_name(cursor):
   for db_row in cursor:
        print db_row
        for col_name in cursor.description:
            if indexOf(cursor.description, col_name) != 0:
                //More things 
        //Return processed stuff