Content deleted Content added
mNo edit summary |
m →Motivation: + wikilink |
||
(27 intermediate revisions by 23 users not shown) | |||
Line 1:
{{Short description|Technique used in relational databases}}
The '''nested set model''' is a
It is based on Nested Intervals, that "are immune to hierarchy reorganization problem, and allow answering ancestor path hierarchical queries algorithmically — without accessing the stored hierarchy relation".<ref>"Nested Intervals Tree Encoding in SQL", Vadim Tropashko; Oracle Corp. Original at https://web.archive.org/web/20111119165033/http://sigmod.org/publications/sigmod-record/0506/p47-article-tropashko.pdf</ref>
==Motivation==
The
An alternative solution is the expression of the hierarchy as a parent-child relation. Hierarchies may be expressed easily by switching to a [[graph database]]. Alternatively, several resolutions exist for the relational model and are available as a
* support for a dedicated [[hierarchy data type]], such as in SQL's [[hierarchical query]] facility;
Line 14 ⟶ 18:
When these solutions are not available or not feasible, another approach must be taken.
==
The
==Example==
Line 53 ⟶ 57:
==Performance==
Queries using nested sets can be expected to be faster than queries using a [[stored procedure]] to traverse an adjacency list, and so are the faster option for databases which lack native recursive query constructs, such as [[MySQL]] 5.x.<ref>{{Citation
| title= Adjacency list vs. nested sets: MySQL
| author= Quassnoi
| date = 29 September 2009
| periodical = Explain Extended
| url =
| accessdate = 11 December 2010
}}</ref> However, recursive SQL queries can be expected to perform comparably for 'find immediate descendants' queries, and much faster for other depth search queries, and so are the faster option for databases which provide them, such as [[PostgreSQL]],<ref>{{Citation
Line 81 ⟶ 85:
| url = http://explainextended.com/2009/09/25/adjacency-list-vs-nested-sets-sql-server/
| accessdate = 11 December 2010
}}</ref> [[MySQL]] used to lack recursive query constructs but added such features in version 8.<ref>{{Cite web|title=MySQL :: MySQL 8.0 Reference Manual :: 13.2.15 WITH (Common Table Expressions)|url=https://dev.mysql.com/doc/refman/8.0/en/with.html|access-date=2021-09-01|website=dev.mysql.com}}</ref>
==Drawbacks==
The use case for a dynamic endless database tree hierarchy is rare. The Nested Set model is appropriate where the tree element and one or two attributes are the only data, but is a poor choice when more complex relational data exists for the elements in the tree. Given an arbitrary starting depth for a category of 'Vehicles' and a child of 'Cars' with a child of 'Mercedes', a foreign key table relationship must be established unless the tree table is
If the tree isn't expected to change often, a properly normalized hierarchy of
<blockquote>Nested Sets is a clever solution – maybe too clever. It also fails to support referential integrity. It’s best used when you need to query a tree more frequently than you need to modify the tree.<ref>{{cite book|last1=Bill|first1=
The model doesn't allow for multiple parent categories. For example, an 'Oak' could be a child of 'Tree-Type', but also 'Wood-Type'. An additional tagging or taxonomy has to be established to accommodate this, again leading to a design more complex than a straightforward fixed model.
Line 99 ⟶ 103:
Using the nested set model as described above has some performance limitations during certain tree traversal operations. For example, trying to find the immediate child nodes given a parent node requires pruning the subtree to a specific level as in the following [[SQL]] code example:
<
SELECT Child.Node, Child.Left, Child.Right
FROM Tree as Parent, Tree as Child
Line 109 ⟶ 113:
WHERE Mid.Left BETWEEN Parent.Left AND Parent.Right
AND Child.Left BETWEEN Mid.Left AND Mid.Right
AND Mid.Node NOT IN (Parent.Node
)
AND Parent.Left = 1 -- Given Parent Node Left Index
</syntaxhighlight>
Or, equivalently:
<
SELECT DISTINCT Child.Node, Child.Left, Child.Right
FROM Tree as Child, Tree as Parent
Line 120 ⟶ 124:
GROUP BY Child.Node, Child.Left, Child.Right
HAVING max(Parent.Left) = 1 -- Subset for those with the given Parent Node as the nearest ancestor
</syntaxhighlight>
The query will be more complicated when searching for children more than one level deep. To overcome this limitation and simplify [[tree traversal]] an additional column is added to the model to maintain the depth of a node within a tree.
Line 153 ⟶ 157:
In this model, finding the immediate children given a parent node can be accomplished with the following [[SQL]] code:
<
SELECT Child.Node, Child.Left, Child.Right
FROM Tree as Child, Tree as Parent
Line 160 ⟶ 164:
AND Child.Left > Parent.Left
AND Child.Right < Parent.Right
AND Parent.
</syntaxhighlight>
==See also==
* [[
* [[Calkin–Wilf tree]]
*[[Tree (data structure)]]▼
* [[Tree traversal]]
▲* [[Tree (data structure)]]
==References==
Line 173 ⟶ 179:
*[http://troels.arvin.dk/db/rdbms/links/#hierarchical Troels' links to Hierarchical data in RDBMSs]
*[http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/ Managing hierarchical data in relational databases]
*[http://pear.php.net/package/DB_NestedSet PHP PEAR Implementation for Nested Sets]
*[http://devmd.com/r/adjacency-list-to-nested-sets-mysql Transform any Adjacency List to Nested Sets using MySQL stored procedures]
*[https://github.com/previousnext/nested-set PHP Doctrine DBAL implementation for Nested Sets]
*[https://github.com/Vince0931/NestedSet R Nested Set]
{{DEFAULTSORT:Nested Set Model}}
|