Monks,
I've just released my first module to CPAN, DBIx::Tree::NestedSet. It implements a nested set tree that uses DBI for storage. For more information on the theoretical advantages of a nested set tree, see the POD, especially the See also section for more in-depth information.
The quick version: Nested set trees allow you to find parents, children, and siblings of nodes in a tree with one SQL statement at the expense of more "costly" updating. Given that most webapps fall into the "many reads, few writes" model a nested set tree can offer significant performance advantages over the typical adjacency list model.
DBIx::Tree::NestedSet includes a CGI::Application and HTML::Template based "helper class" named DBIx::Tree::NestedSet::Manage that gives you a CGI (or mod_perl) based interface to your nested set tree, partially to be useful and partially to demonstrative of the API.
Rather than me blathering on repeating what's already in the documentation, please look at the POD and the README for further info.
I'm looking for folks to test this on other RDBMSs and patches are always welcome.
It's a testament to the mighty CPAN (or a slight on my skills. . .) that I've been programming perl for over 5 years and this is the first module I've needed/wanted that wasn't already up there in one form or another.
-Any sufficiently advanced technology is
indistinguishable from doubletalk.
Cheers - L~R
Indeed, I do want comments on how to improve the code. I'll definitely check out the ladder.
-Any sufficiently advanced technology is
indistinguishable from doubletalk.
Im not sure how you have implemented the drop/delete node, but it seems that if i would drop a node with 1000 descendants it would cost me 1000 selects, 1000 deletes and 1000 updates.
This is is usually done with two statements, one delete and one update.
If you have this tree and you would like to drop node C and it's descendants:
|
1 A 12
/-----------------+-----------------\
| | |
2 B 3 4 C 9 10 D 11
/-----------\
| |
5 E 6 7 F 8
DELETE
FROM tree
WHERE lft BETWEEN :lft AND :rgt
:lft = 4
:rgt = 9
UPDATE tree
SET lft = CASE
WHEN lft > :lft THEN lft - :gaps
ELSE lft
END,
rgt = CASE
WHEN rgt > :rgt THEN rgt - :gaps
ELSE rgt
END
WHERE rgt > :lft
:gaps = 9 - 4 + 1 (:rgt - :lft + 1)
:lft = 4
:rgt = 9
And the result:
|
1 A 6
/-----------\
| |
2 B 3 4 D 5
The Nested Set algorithm is one of my favorites, it's very efficient and portable. It can handle large trees with out problems.
Thanks for the algorithm improvements. This has been applied to the next version of DBIx::Tree::NestedSet, along with a bunch of other fixes and improvements.
-Any sufficiently advanced technology is
indistinguishable from doubletalk.
perlmonks.org content © perlmonks.org and Hansen, Hero Zzyzzx, Limbic~Region, perrin
prlmnks.org © 2006 edmund von der burg (eccles & toad)
v 0.03