数据库结构和查询分层数据和数据树

时间:2010-12-13 23:28:47

标签: php mysql database-design cassandra hierarchical-data

  

可能重复:
  What is the most efficient/elegant way to parse a flat table into a tree?

我觉得这很棘手,并希望就此事提出一些意见。 我试图存储具有未知数量的级别和分支的分层数据(树状)。我希望能够随时添加新的并删除任何内容。

由于用户群众多,我需要能够一次性从层次结构中的任何节点查询所有子ID,并且有效率。

让我们假设一个网站的例子,家庭在Facebook上社交和更新他们的状态,并且在任何时候你可以查看家庭成员“Wall”,其中还包括他们下面的人的所有最新状态更新按时间顺序排列在层次结构中。

显然,一旦你拥有了这个家庭成员节点的家庭成员id的数组,那么获取帖子就很容易了。

让我们举一个简单的表结构示例:

id  |  parentId  |  name
________________________

1   |    NULL    |  John
2   |     1      |  Peter
3   |     1      |  Bob
4   |     3      |  Emma
5   |     2      |  Sam
6   |     4      |  Gill
等等......你明白了。

除非你认为需要调整结构,否则我需要能够用这样的方法做到这一点。

我已阅读mySql nested set model。 这似乎非常繁琐,如果某些事情没有正确更新并且会弄乱一切,那么这可能是不可靠的。

我习惯使用php和mysql,但已经阅读了cassandra和thrift。不确定这会更容易吗?

3 个答案:

答案 0 :(得分:1)

已经有很好的方法比你提出的解决方案更简单。

以下是一些解释如何操作的链接(我们自己使用它来解决您描述的相同问题并且效果很好)。

这使得插入/更新更复杂,但选择 far 树结构的部分更快(只有一个查询)。它允许在一个查询中查找任何给定节点的所有子节点,并通过一个查询查找给定节点的所有祖先。

答案 1 :(得分:0)

所以我想我已经提出了一个想法。

我反对嵌套集模型的原因是因为它似乎仍然不是最好的方式,并且不会成为理想的性能解决方案。

我将介绍我一直在考虑的建议解决方案。 这个概念意味着创建一个hierarchal map表来跟踪每个家庭成员/节点之间的所有关系。

它的工作方式是:

使用此地图表结构:

id  |  fMemberId   |   parentid
=====================================
1   |      3       |       2  
2   |      4       |       3
3   |      4       |       2

1)当一个新的家庭成员被创建为父母的孩子时,我们将获取父母ID,并在我们的家庭成员表中创建一个新行,并将父ID设置为将来的其他用途和功能。

2)创建此行后,我们将创建包含新系列成员的所有父ID的新行。

快速执行此操作的方法是从新的系列成员中获取父ID,并对map表执行查询,以查找系列成员标识与所有行相同的所有行。新的家庭成员父ID,然后在php中存储一个数组,该数组需要与map表中新的家庭成员id一起存储所需的后续父ID。 这将只需要一个sql查询来获取所有父ID 以添加它们而不是基于节点数的多个查询

这意味着当我们查看家庭成员的帖子时,我们可以查询数据库,只查询map表中的行,以获取当前家庭成员的所有子ID并随后查询其他表格用于发布数据。

主要的权衡是这种系统所需的潜在存储量。 但是我相信读取速度会更快,因为没有条件SQL语句,也可能以这种方式快速写入db。

我们可以通过使用InnoDB的群集ID分配初始家庭ID索引并根据家庭ID创建一个包含“下一个家庭成员ID”的新表来解决这个问题。

同样可靠,如果没有写入一行就很容易将其添加进去。它可以防止为了创建成员而不断编辑行。

您对此有何看法?

到目前为止,这在我看来似乎是一个好方法。想到这里去了很多想法。我也相信它可以随着时间的推移而改进,并且能够存储每个成员的id的数组而不是所有成员。仍然试图解决这个问题!

答案 2 :(得分:0)

是的,您的解决方案称为传递闭包。我之前写过:

您还需要零长度路径,例如2-2,3-3,4-4。