And I learned a cute trick for searching hierarchies. You know how to store a tree in a table, right: you give each node an id and store the parent id of the node as well:
CREATE TABLE node ( id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, parent INT, payload TEXT )
So now you can find the children of node 5 easily: SELECT * FROM node WHERE parent=5. But it's hard to select all the children of node 5. That requires a tree traversal, which involves lots of database queries, which gets jugly fast.
The cute trick is to build another table containing the path of each node (".1.5.12.19." means that this is node 19 whose parent is node 12 whose parent is node 5 whose parent is node 1). Then finding node 5 and its children is as simple as:
SELECT id,path FROM paths WHERE path LIKE "%.5.%"
Suuuper sneaky! I'm really beginning to appreciate how different it is to program in SQL...
--Nat
HTML::Pager? (Score:1)
I think HTML::Pager [cpan.org] fits the bill (atleast somewhat). Can't say I've ever used it, though. Looks like it depends on HTML::Template for its output (although it claims it can still be used without it). HTH.
Data::Page (Score:2, Informative)
You probably want to investigate Data::Page [cpan.org] and it's cousin Data::PageSet [cpan.org].
I wrote a paging module before. I wouldn't wish the edge cases on anybody.
-Dom
Re:Data::Page (Score:1)
-Dom
Re:Data::Page (Score:2)
--Nat
Re:Data::Page (Score:1)
Cute Tricks and Premature Optimizations (Score:2)
Beware that this is a premature optimization.
While this technique works fine with a static tree, it makes tree transformations hideously difficult. Imagine the pain that comes from moving node 12 to be a sibling of node 5, or removing node 5 and consequently promoting their children up a level.
The other technique
Re:Cute Tricks and Premature Optimizations (Score:1)
-Dom
Re:Cute Tricks and Premature Optimizations (Score:2)
Re:Cute Tricks and Premature Optimizations (Score:2)
I personally don't think that the "ton of SELECTs" is all that horrible. That's probably my personal style though.
It starts out with something like this:
...which returns a list of IDs. That list of IDs then goes into a new SQL statement. The IDs are also pushed into a list that contains all IDs returned from your per-leve
Re:Cute Tricks and Premature Optimizations (Score:2)
I've written code as the one you describe dozens of times and I must say that it certainly was "fast enough". I'd be worried if I had very deep trees though, as that would be when it could become costly.
But then why store a tree in an RDB? Wouldn't XPath be a *lot* more pleasant to access random things in a tree? ;)
-- Robin Berjon [berjon.com]
Hierarchies (Score:2)
Fabian Pascal talks about hierarchies a fair amount in his book Practical Issues in Database Management. Interesting stuff.
Data::Page with Class::DBI (Score:2)
Casey West
You'd be better off converting hierarchies to sets (Score:1)
I've been doing a bunch of hierarchy work recently in SQL, and the hands-down best way to do the type of typical hierarchy queries that I do in SQL is to store (or at least additionally represent) hiearchies as sets.
See, SQL is a set-operation language. So having hierarchies stored as an adjacency list (e.g. employee table has a 'manager' column) -- although sufficient -- forces you out of SQL and into a procedural language for tree-walking.
Imagine you want to get "this person's management chain" or
Re:You'd be better off converting hierarchies to s (Score:1)
Here's the decoder guide -- not actual SQL.
My Management Chain: Select where left LESS THAN my_left AND right GREATER THAN my_right
My Vast Empire Select where left GREATER THAN OR EQUAL TO my_left AND right LESS THAN OR EQUAL TO my_right Joel Noble
Finding subtrees (Score:1)
Re:Finding subtrees (Score:2)
Thanks!
--Nat
Materialized Path (Score:1)
http://www.dbazine.com/tropashko4.html
tree traversal in SQL (Score:1)
Nobody has mentioned Oracle's CONNECT BY [oracle.com]. Hierarchical queries in one statement!
I doubt Ziggy is aware of this, but the tree hack you describe is roughly how ASPN [activestate.com] works. Ugly and inflexible, yes, but it gave us the performance we wanted, without having to shell out for Oracle.
It may have been a premature optimization. I personally was horrified by the idea during the design meetings. But it works very well in practice and it's easy to understand.