在关系数据库中存储树结构的已知方法有哪些?

时间:2010-07-29 12:59:07

标签: mysql design-patterns tree relational-database

"put a FK to your parent" method,即每个记录都指向它的父级 这是一个难以阅读的行动,但很容易维护。

然后有一个“目录结构键”方法:

0001.0000.0000.0000 main branch 1
0001.0001.0000.0000 child of main branch one
etc

这很容易阅读,但难以维护 有什么其他方式和他们的利弊/专业人士?

4 个答案:

答案 0 :(得分:49)

一如既往:没有最佳解决方案。每种解决方案都会使不同的事情更容易或更难适合您的解决方案取决于您最常做的操作。

带有父ID的天真方法:

优点:

  • 易于实施

  • 轻松将大子树移动到另一个父级

  • 插入便宜

  • 可在SQL

  • 中直接访问的字段

缺点:

  • 检索整棵树是递归的,因此很昂贵

  • 找到所有父母也很贵(SQL不知道递归......)

修改预订树遍历(保存起点和终点):

优点:

  • 检索整棵树既简单又便宜

  • 找到所有父母便宜

  • 可在SQL

  • 中直接访问的字段
  • 奖励:您也在其父节点中保存子节点的顺序

缺点:

  • 插入/更新可能非常昂贵,因为您可能需要更新大量节点

在每个节点中保存路径:

优点:

  • 找到所有父母便宜

  • 检索整棵树很便宜

  • 插入便宜

缺点:

  • 移动整棵树很贵

  • 根据您保存路径的方式,您将无法直接在SQL中使用它,因此您始终需要获取&解析它,如果你想改变它。

我更喜欢最后两个中的一个,具体取决于数据更改的频率。

另请参阅:http://media.pragprog.com/titles/bksqla/trees.pdf

答案 1 :(得分:18)

修改后的预订树遍历

这是一种使用非递归函数(通常是单行SQL)从数据库中检索树的方法,但代价是更新一点。

Diagram showing numbered hierarchical tree **

Sitepoint文章Storing Hierarchical Data in a Database的第2部分了解更多详情。

答案 2 :(得分:4)

我认为存储分层数据结构的“黄金方式”是使用分层数据库。例如,HDB。这是一个很好地处理树木的关系数据库。如果你想要更强大的东西,LDAP可能会为你做。

SQL数据库不适合这种抽象拓扑。

答案 3 :(得分:0)

我认为用关系数据库构建树结构并不困难。

但是,面向对象的数据库可以更好地用于此目的。

使用面向对象的数据库:

parent has a set of child1  
child1 has a set of child2  
child2 has a set of child3  
...  
...

在面向对象的数据库中,您可以非常轻松地构建此结构。

在关系数据库中,您必须将外键维护为父级。

parent  
id  
name  

child1  
parent_fk  
id  
name 

child2  
parent_fk  
id  
name  

..

基本上,在构建树结构时,您必须连接所有这些表,或者您可以遍历它们。

foreach(parent in parents){
   foreach(child1 in parent.child1s)
    foreach(child2 in child1.child2s)

...