问题描述
有"将FK放在您的父母身上" >,即每个记录指向其父母.
这很难阅读动作,但很容易维护.
然后有一个"目录结构密钥"方法:
0001.0000.0000.0000 main branch 1 0001.0001.0000.0000 child of main branch one etc
这很容易阅读,但很难维护.
其他方法及其缺点/优点是什么?
推荐答案
一如既往:没有最好的解决方案.每个解决方案都使不同的事情变得更容易或更难.正确的解决方案取决于您最大的操作.
parent-id的天真方法:
专利:
-
易于实现
-
易于将大子树移至另一个父母
-
插入物很便宜
-
需要在SQL
中直接访问的字段
cons:
-
检索整棵树是递归的,因此昂贵
-
找到所有父母也很昂贵(SQL不知道递归...)
修改的预订树遍历(保存起始和终点):
专利:
-
检索一棵树很容易且便宜
-
找到所有父母都很便宜
-
需要在SQL
中直接访问的字段 -
奖金:您也保存其parenthode中的子节点的顺序
cons:
- 插入/更新可能非常昂贵,因为您可能必须更新许多节点
保存每个节点的路径:
专利:
-
找到所有父母都很便宜
-
检索一棵树很便宜
-
插入很便宜
cons:
-
移动一棵树很昂贵
-
取决于您保存路径的方式,您将无法直接在SQL中使用它,因此,如果您想更改它,您将始终需要获取和解析.
闭合表
专利:
-
易于实现
-
找到所有父母都很便宜
-
插入很便宜
-
检索全树是便宜的
cons:
-
需要一个附加的表
-
与其他方法相比,占用了很多空间
-
移动子树是昂贵的
我更喜欢最后两个之一,具体取决于数据的频率.
另请参见: http://media.pragprog.com/titles/bksqla/trees .pdf
其他推荐答案
修改的预订树遍历
这是一种使用非收回函数(通常是SQL的单行)从数据库中检索树的方法,以更新的费用更棘手.
Sitepoint文章的第2节将层次数据存储在数据库中更多细节.
其他推荐答案
我会说存储层次数据结构的"黄金方式"是使用层次数据库.例如,HDB.这是一个关系数据库,可以很好地处理树木.如果您想要更强大的东西,LDAP可能会为您做.
SQL数据库不适合此抽象拓扑.
问题描述
There is the "put a FK to your parent" method, i.e. each records points to it's parent.
Which is a hard for read actions but very easy to maintain.
And then there is a "directory structure key" method:
0001.0000.0000.0000 main branch 1 0001.0001.0000.0000 child of main branch one etc
Which is super easy to read, but hard to maintain.
What are the other ways and their cons/pros?
推荐答案
As always: there is no best solution. Each solution makes different things easier or harder. The right solution for you depends on which operation you will do most.
Naive Approach with parent-id:
Pros:
Easy to implement
Easy to move a big subtree to another parent
Insert is cheap
Needed Fields directly accessible in SQL
Cons:
Retrieving a whole tree is recursive and therefore expensive
Finding all parents is expensive too ( SQL doesn't know recursions... )
Modified Preorder Tree Traversal ( saving a start- & end-point) :
Pros:
Retrieving a whole tree is easy and cheap
Finding all parents is cheap
Needed Fields directly accessible in SQL
Bonus: you're saving the order of childnodes within its parentnode too
Cons:
- Inserting / Updating can be very expensive, as you'll maybe have to update a lot of nodes
Saving a path in each Node:
Pros:
Finding all parents is cheap
Retrieving a whole tree is cheap
Inserting is cheap
Cons:
Moving a whole tree is expensive
Depending on the way you save the path, you won't be able to work with it directly in SQL, so you'll always need to fetch & parse it, if you want to change it.
Closure table
Pros:
Easy to implement
Finding all parents is cheap
Inserting is cheap
Retrieving whole trees is cheap
Cons:
Needs an additional table
Takes up a lot of space compared to other approaches
Moving a subtree is expensive
I'd prefer one of the last two, depending on how often the data changes.
See also: http://media.pragprog.com/titles/bksqla/trees.pdf
其他推荐答案
Modified Preorder Tree Traversal
This is a method which uses a non-recursive function (usually a single line of SQL) to retrieve trees from the database, at the cost of being a little trickier to update.
Section 2 of the Sitepoint article Storing Hierarchical Data in a Database for more detail.
其他推荐答案
I'd say the "golden way" to store a hierarchical data structure is to use a hierarchical database. Such as, for instance, HDB. That's a relational database that handles trees quite well. If you want something more powerful, LDAP might do for you.
A SQL database is ill-suited to this abstract topology.