<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Hierarchies (trees) in SQL Server 2005</title><link>http://blogs.msdn.com/b/anthonybloesch/archive/2006/02/15/hierarchies-in-sql-server-2005.aspx</link><description>There is much debate about how to implement hierarchies (trees) relationally in SQL Server. I decided to test the main techniques out and see which performed best for my application.</description><dc:language>en-US</dc:language><generator>Telligent Evolution Platform Developer Build (Build: 5.6.50428.7875)</generator><item><title>re: Hierarchies (trees) in SQL Server 2005</title><link>http://blogs.msdn.com/b/anthonybloesch/archive/2006/02/15/hierarchies-in-sql-server-2005.aspx#10333582</link><pubDate>Thu, 26 Jul 2012 00:58:37 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10333582</guid><dc:creator>Jeff Moden</dc:creator><description>&lt;p&gt;I know this is an old thread but ran across it while doing a bit of research. &amp;nbsp;I&amp;#39;ve got to ask, where is the code that built the 20,000 row sample and where is the code that you actually tested?&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10333582" width="1" height="1"&gt;</description></item><item><title>re: Hierarchies (trees) in SQL Server 2005</title><link>http://blogs.msdn.com/b/anthonybloesch/archive/2006/02/15/hierarchies-in-sql-server-2005.aspx#10228893</link><pubDate>Sat, 22 Oct 2011 15:11:03 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10228893</guid><dc:creator>Kenorasis</dc:creator><description>&lt;p&gt;It seems to me that the Nested Sets approach is storing more information than the others, namely, the ORDER in which sibling nodes appear. In the example above, if we wanted Denise to appear to the left of Charles, we would need another field (and a mechanism to manage the value of that field) to store the order in both the Adjacency and the Path techniques. &lt;/p&gt;
&lt;p&gt;I know the original post is a bit old at this point, but it would be interesting to see how one could build a mechanism to store the order of sibling nodes into the Adjacency and Path technique and then compare all three for speed. &lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10228893" width="1" height="1"&gt;</description></item><item><title>re: Hierarchies (trees) in SQL Server 2005</title><link>http://blogs.msdn.com/b/anthonybloesch/archive/2006/02/15/hierarchies-in-sql-server-2005.aspx#10173384</link><pubDate>Fri, 10 Jun 2011 16:12:34 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:10173384</guid><dc:creator>Kalin</dc:creator><description>&lt;p&gt;In support of Marc Buzina&amp;#39;s approach, here is my experience with a project that currently holds around 37,000 tree nodes and is always expected to grow, although not very fast.&lt;/p&gt;
&lt;p&gt;We started as usual with the adjacency list model. As the tree kept growing we moved to nested sets trying to improve response time. The tree kept growing and timeouts and concurrency problems made it clear that we needed another aproach. (Our nested sets implementation did not use gaps and inserts/updates/deletes involved a lot of recalculations of intervals. Also most probably it was not the most optimized implementation.) We came across something called &amp;quot;Transitive closure&amp;quot; which maps to the structure proposed by mbuzina.&lt;/p&gt;
&lt;p&gt;Now our Tree table has three columns: NodeId, ParentId, SiblingNumber. The TreeHierarchy table has AncestorId, DescendantId, Distance and holds about 240,000 records. It is maintained through triggers on the Tree table. Insert/update/delete of a node now affect only a small number of records in TreeHierarchy, so deadlocks and timeouts do not worry us any more. Retrieving the whole tree takes less than 0.6 sec. We never need to do this anyway, because the end user would have to wait a long long time for the browser to show all 37,000 nodes, so we load on demand only branches that the user decides to delve deeper into. The maximum depth currently is 11, and the most &amp;quot;fertile&amp;quot; parents have between 300 and 680 children.&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=10173384" width="1" height="1"&gt;</description></item><item><title>re: Hierarchies (trees) in SQL Server 2005</title><link>http://blogs.msdn.com/b/anthonybloesch/archive/2006/02/15/hierarchies-in-sql-server-2005.aspx#9922891</link><pubDate>Mon, 16 Nov 2009 11:28:06 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9922891</guid><dc:creator>Jon</dc:creator><description>&lt;p&gt;I don't know this Celko. Wikipedia says:&lt;/p&gt;
&lt;p&gt;He is often corrected by product experts including a number of the SQL Server MVP's which lead to protracted discussions which more often than not he comes out losing.&lt;/p&gt;
&lt;p&gt;All I know is he is a brag who's not helping average programmers... I have 20+ experience and paid $1000s of a day. Ashol. Same with you Chandrashekar. I bet you dont even know what you are saying.&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9922891" width="1" height="1"&gt;</description></item><item><title>re: Hierarchies (trees) in SQL Server 2005</title><link>http://blogs.msdn.com/b/anthonybloesch/archive/2006/02/15/hierarchies-in-sql-server-2005.aspx#9893608</link><pubDate>Thu, 10 Sep 2009 15:23:48 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9893608</guid><dc:creator>OrbMan</dc:creator><description>&lt;p&gt;The high value for all descendents of the path model makes me think the path column was not indexed - can you confirm whether it was or not?&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9893608" width="1" height="1"&gt;</description></item><item><title>re: Hierarchies (trees) in SQL Server 2005</title><link>http://blogs.msdn.com/b/anthonybloesch/archive/2006/02/15/hierarchies-in-sql-server-2005.aspx#9595151</link><pubDate>Fri, 08 May 2009 01:31:43 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9595151</guid><dc:creator>Niclas</dc:creator><description>&lt;p&gt;Hi there, &lt;/p&gt;
&lt;p&gt;I have a problem which i wonder if you could point me in direction how to solve. &lt;/p&gt;
&lt;p&gt;I have a tree structure where each node have a &amp;quot;rating&amp;quot; column (int). For &amp;quot;composite&amp;quot; nodes, nodes with children the rating column should take the value of the max value of all its children. What kind of structure do i represent such a tree best in? &lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9595151" width="1" height="1"&gt;</description></item><item><title>re: Hierarchies (trees) in SQL Server 2005</title><link>http://blogs.msdn.com/b/anthonybloesch/archive/2006/02/15/hierarchies-in-sql-server-2005.aspx#9530459</link><pubDate>Fri, 03 Apr 2009 12:37:27 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9530459</guid><dc:creator>Yoseph</dc:creator><description>&lt;p&gt;When using Nested set, if you want to retrieve all the tree (root node and all of its descendants), all you need to do is: SELECT * FROM tree ORDER BY left ASC. The process of generating the tree is supposed to be handled by your application. So the query needed is only 1, not 6072.&lt;/p&gt;
&lt;p&gt;You can see the implementation of this tree in PHP ORM framework (Propel) -&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel="nofollow" target="_new" href="http://propel.phpdb.org/trac/wiki/Users/Documentation/1.3/Tree/NestedSet"&gt;http://propel.phpdb.org/trac/wiki/Users/Documentation/1.3/Tree/NestedSet&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Here is some code of the implementation of retrieving tree:&lt;/p&gt;
&lt;p&gt;public static function retrieveTree(PropelPDO $con = null)&lt;/p&gt;
&lt;p&gt;	{&lt;/p&gt;
&lt;p&gt;		$c = new Criteria(TreePeer::DATABASE_NAME);&lt;/p&gt;
&lt;p&gt;		$c-&amp;gt;addAscendingOrderByColumn(self::LEFT_COL);&lt;/p&gt;
&lt;p&gt;		/*&lt;/p&gt;
&lt;p&gt;		EXECUTE QUERY:&lt;/p&gt;
&lt;p&gt;		SELECT * FROM tree ORDER BY lft ASC&lt;/p&gt;
&lt;p&gt;		*/&lt;/p&gt;
&lt;p&gt;		$stmt = TreePeer::doSelectStmt($c, $con);&lt;/p&gt;
&lt;p&gt;		if (false !== ($row = $stmt-&amp;gt;fetch(PDO::FETCH_NUM))) {&lt;/p&gt;
&lt;p&gt;			$root = new Tree();&lt;/p&gt;
&lt;p&gt;			$root-&amp;gt;hydrate($row);&lt;/p&gt;
&lt;p&gt;			$root-&amp;gt;setLevel(0);&lt;/p&gt;
&lt;p&gt;			$tree = self::hydrateDescendants($root, $stmt);&lt;/p&gt;
&lt;p&gt;			$stmt-&amp;gt;closeCursor();&lt;/p&gt;
&lt;p&gt;			return $tree;&lt;/p&gt;
&lt;p&gt;		}&lt;/p&gt;
&lt;p&gt;		return false;&lt;/p&gt;
&lt;p&gt;	}&lt;/p&gt;
&lt;p&gt;Note: only 1 query is executed.&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9530459" width="1" height="1"&gt;</description></item><item><title>re: Hierarchies (trees) in SQL Server 2005</title><link>http://blogs.msdn.com/b/anthonybloesch/archive/2006/02/15/hierarchies-in-sql-server-2005.aspx#9397851</link><pubDate>Thu, 05 Feb 2009 11:41:18 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9397851</guid><dc:creator>mbuzina</dc:creator><description>&lt;p&gt;I am missing the classical datawarehouse approach. I know it is mostly focused on querying, but in my personal experiance, the insert performance is not too bad, depending on the model of inserts.&lt;/p&gt;
&lt;p&gt;I have successfully used a combination of adjencency with a cache table for holding all relationships. I would have the following cache table&lt;/p&gt;
&lt;p&gt;emp_cache&lt;/p&gt;
&lt;p&gt;descendant,ancestor,distance&lt;/p&gt;
&lt;p&gt;2,2,0&lt;/p&gt;
&lt;p&gt;1,1,0&lt;/p&gt;
&lt;p&gt;1,2,1&lt;/p&gt;
&lt;p&gt;3,3,0&lt;/p&gt;
&lt;p&gt;3,2,1&lt;/p&gt;
&lt;p&gt;4,4,0&lt;/p&gt;
&lt;p&gt;4,3,1&lt;/p&gt;
&lt;p&gt;4,2,2&lt;/p&gt;
&lt;p&gt;5,5,0&lt;/p&gt;
&lt;p&gt;5,3,1&lt;/p&gt;
&lt;p&gt;5,2,1&lt;/p&gt;
&lt;p&gt;Additionally I would add a depth column to the base table, which allows a quicker computation of the distance value inside the trigger maintaining the cache and have the cache table indexed (depending on your query patterns). Inserting, updateing &amp;amp; deleting is done exactly as with adjacency, which makes sure there are no loops at all. Querying will use the cache table (&amp;amp; depth column). Querying the cache is quite natural to sql.&lt;/p&gt;
&lt;p&gt;I used this to handle a cost center structure which was 17 levels deep and handled approx. 15.000 nodes.&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9397851" width="1" height="1"&gt;</description></item><item><title>re: Hierarchies (trees) in SQL Server 2005</title><link>http://blogs.msdn.com/b/anthonybloesch/archive/2006/02/15/hierarchies-in-sql-server-2005.aspx#9143106</link><pubDate>Wed, 26 Nov 2008 05:06:28 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9143106</guid><dc:creator>dan</dc:creator><description>&lt;p&gt;To the person making comments that sound a bit nasty, and mentioning NP-Complete. &amp;nbsp;it may come as a surprise to you, but not everyone releases everything they have, and there are indeed some solutions out there you have not heard of.&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9143106" width="1" height="1"&gt;</description></item><item><title>re: Hierarchies (trees) in SQL Server 2005</title><link>http://blogs.msdn.com/b/anthonybloesch/archive/2006/02/15/hierarchies-in-sql-server-2005.aspx#1997825</link><pubDate>Sat, 31 Mar 2007 08:35:21 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:1997825</guid><dc:creator>Cesar</dc:creator><description>&lt;p&gt;I know it is too late to ask, but where is the data to test your experiment?&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1997825" width="1" height="1"&gt;</description></item></channel></rss>