我必须构建一个包含大约300个节点的树。树没有深度限制。所以它可以有3或15个级别。每个节点可以拥有无限数量的孩子。
优先级是尽可能快地获得完整的树/子树,但我还需要有时添加节点或移动节点,但不是经常这样。
我想知道在数据库中存储树的最佳方法,以及在php中检索数据的最佳方法。
答案 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