在关系数据库中存储树结构的已知方法是什么?
有“把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
我想说存储分层数据结构的“黄金之路”是使用分层数据库。 比如,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) ...