在关系数据库中存储树结构的已知方法是什么?

有“把FK给你的父母”的方法 ,即每个logging指向它的父母。
这是一个难以阅读的行动,但很容易维护。

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

0001.0000.0000.0000 main branch 1 0001.0001.0000.0000 child of main branch one etc 

这是超级容易阅读,但很难维护。
什么是其他的方式和他们的利弊?

一如既往:没有最好的解决scheme。 每个解决scheme使不同的事情变得更容易或更难 对你来说正确的解决scheme取决于你最擅长的操作。

天真的方法与父母身份证:

优点:

  • 容易实施

  • 容易移动一个大的子树到另一个父母

  • 插入很便宜

  • 需要在SQL中直接访问的字段

缺点:

  • 检索整个树是recursion的,因此是昂贵的

  • find所有的父母也是昂贵的(SQL不知道recursion…)

修改先序树遍历(保存起点和终点):

优点:

  • 检索整个树是容易和便宜的

  • find所有的父母是便宜的

  • 需要在SQL中直接访问的字段

  • 奖金:您也在其父节点中保存了子节点的顺序

缺点:

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

在每个节点中保存path:

优点:

  • find所有的父母是便宜的

  • 检索整棵树很便宜

  • 插入很便宜

缺点:

  • 移动整棵树是昂贵的

  • 根据保存path的方式,您将无法直接在SQL中使用它,所以如果您想要更改,您总是需要获取并parsing它。

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

另见: http : //media.pragprog.com/titles/bksqla/trees.pdf

修改先序树遍历

Sitepoint文章的第2部分在数据库中存储分层数据

替代文字graphics/sitepoint_numbering.gif

我想说存储分层数据结构的“黄金之路”是使用分层数据库。 比如,build屋局。 这是一个处理树木的关系数据库。 如果你想要更强大的function,LDAP可能会帮你。

一个SQL数据库不适合这个抽象的拓扑结构。

我不认为用关系数据库build立一个树结构是很困难的。

但是,面向对象的数据库对于这个目的会更好。

使用面向对象的数据库:

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

在面向对象的数据库中,你可以很容易地构build这个结构。

在关系数据库中,您将不得不将外键维护到父级。

 parent id name child1 parent_fk id name child2 parent_fk id name .. 

从本质上讲,当你构build你的树结构时,你将不得不join所有这些表格,或者你可以遍历它们。

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