Just to throw it into the mix, I have used a different approach to this ever since I first threw together a tree based CMS in 1997. I don't know that it is a good approach, but it is fast on retrieval and capable of quick and easy cascading deletes (which I make optional on an object-property basis).
As with adjacency model, there is ID and ParentID. There is also a separate displayorder field which allows any integer from 0-99 and the global display order which is a string concatenated set of display orders for all of the antecedents of a record and is often set as an index in the database. Example: ID ParentID Title DisplayOrder GlobalDisplayOrder 1 0 Home 01 01 2 0 About Us 02 02 3 2 History 01 0201 4 2 Founders 02 0202 5 2 Employees 03 0203 6 0 Products 03 03 7 6 Clothing 01 0301 8 6 Shoes 02 0302 9 0 Contact Us 04 04 Retrieval is easy - just order by global display order and filter based on your exact requirements. It is particularly useful for partially expanded trees You are ordering by a varchar, but if it is an index, performance is still good. Adding a new record is easy as you just get the parent ID to look up the parents global display order and then concatenate the new instances display order (adding a trailing 0 if only a single digit). No changes to set numbering are required. Cascading deletes (if required) are fairly easy keying off of parent ID's. For systems with high retrieval and moderate add/delete requirements, I've found this performs very well. Obviously the pain point is changing the display order of high level properties as the changes in their display orders must propegate recursively down the tree, but a simple trigger seems to do the job. Probably not as good as the other ideas, but any thoughts on the approach for the scenario listed above (lots of reads, some add/deletes and few display order edits) would be interesting. Naturally the global display order field is auto generated, so the additional data really isn't an issue as it doesn't need to be maintained. I tend to optimize for performance rather than normalization as disk space is usually less precious than processor cycles and I use automated tools for managing all content so I don't need to worry about developers manually creating code that might forget to update all artifacts - the intelligence is encapsulated in the DAL. Best Wishes, Peter -----Original Message----- From: Barney Boisvert [mailto:[EMAIL PROTECTED] Sent: Wednesday, February 01, 2006 3:18 PM To: CF-Talk Subject: Re: Nested Set Model Adjacency lists employ a parentID, so every node knows who it's parent is, but that's it. Nested sets use a set of numbers (starting at 'left' and ending at 'right', typically) for each node, and the relationships between the sets dictate hierarchy. Adjacency list are simple and fast for tree manipulation, but extracting data can be cumbersome. There also isn't any way to order the children of a given node. Nested sets, on the other hand, are more complex to work with, and slower for tree manipulation. However, they are both very fast and very simple to make complex queries against, once you understand how they work. Nested sets also have implicit ordering of ALL nodes, both hierarchially, and within a given level of the hierarchy. So with a nested set you can swap two children of a node, and the tree structure itself will remember that, without the need for a separate ordering key. For example, with your "ancestors" query, using adjacency list, you have to find the node's parent, if it's not null, find it's parent, etc., repeating until you reach a node that has a null parent (the root). With a nested set, you do this: SELECT id, name FROM myTable WHERE left < ( SELECT left FROM myTable WHERE id = #nodeId# ) AND right > ( SELECT right FROM myTable WHERE id = #nodeId# ) ORDER BY left That'll return a recordset that contains all the ancestors of the given node. Change the < and > to <= and >= and you'll get the node itself, and all it's ancestors. Reverse the < and > and you'll get decendants of the node. Etc. >From what you describe, nested sets is probably better for your scenario. You have a relatively static tree hierarchy (compared to the amount of recall), and the recall you need is very tree-centric. Consequently you'll probably find things easier with nested sets than with an adjacency list, and you might get a performance boost out of it as well. cheers, barneyb On 2/1/06, Mike Little <[EMAIL PROTECTED]> wrote: > >I'm not sure what you wish to do with this level count, but be > >careful if you plan on storing it in the original table. The level > >count is already stored inherently in the table through its structure > > brad, are you saying that i could do without the level column and rely > instead on the query to determine which level each category is on? the > reason i wanted this column was so that i could create breadcrumbs > with a simple query. > > also, from the other posts (thanks heaps by the way) is it not > necessary to utilise a parent_id column using nested sets? > > my client wishes to be able to move categories to any other category > and also reorder a category within a particular level, so you can > imagine i am all twisted about on this at the moment. > > mike -- Barney Boisvert [EMAIL PROTECTED] 360.319.6145 http://www.barneyb.com/ Got Gmail? I have 100 invites. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~| Message: http://www.houseoffusion.com/lists.cfm/link=i:4:231026 Archives: http://www.houseoffusion.com/cf_lists/threads.cfm/4 Subscription: http://www.houseoffusion.com/lists.cfm/link=s:4 Unsubscribe: http://www.houseoffusion.com/cf_lists/unsubscribe.cfm?user=89.70.4 Donations & Support: http://www.houseoffusion.com/tiny.cfm/54

