A good read to start with is Hierarchical Data In MySQL (which I used to be able to find on the MySQL.com website, arghh)
Read It?
Here's how it could be done with the adjacency list model. But only for a known fixed amount of nesting (four nesting levels for this example).
I would find out which of my pages are root pages (of the tree). Then select only those with a query. Put the LIMIT x,x
in this select statement.
After that, the following statement: (or something like it)
string query = "
SELECT t1.name AS lev1, t2.name as lev2, t3.name as lev3, t4.name as lev4
FROM category AS t1
LEFT JOIN category AS t2 ON t2.parent = t1.category_id
LEFT JOIN category AS t3 ON t3.parent = t2.category_id
LEFT JOIN category AS t4 ON t4.parent = t3.category_id
WHERE t1.name IN('ELECTRONICS', '<some other name>');
";
Could return something like this:
+-------------+----------------------+--------------+-------+
| lev1 | lev2 | lev3 | lev4 |
+-------------+----------------------+--------------+-------+
| ELECTRONICS | TELEVISIONS | TUBE | NULL |
| ELECTRONICS | TELEVISIONS | LCD | NULL |
| ELECTRONICS | TELEVISIONS | PLASMA | NULL |
| ELECTRONICS | PORTABLE ELECTRONICS | MP3 PLAYERS | FLASH |
| ELECTRONICS | PORTABLE ELECTRONICS | CD PLAYERS | NULL |
| ELECTRONICS | PORTABLE ELECTRONICS | 2 WAY RADIOS | NULL |
| etc... | etc... | etc... | |
+-------------+----------------------+--------------+-------+
The trick is to use only the root names of the query with limit (or ID's if you want) in the IN()
statement of the query.
This should perform pretty good still (in theory).
The principle of the above query could also be used to find out how many descendants are in a root of a tree (with a little GROUP BY
and COUNT()
magic ;) Also, you could find out which of your pages are roots with this principle (though I would save that in the tabledata for performance reasons)
If you want a dynamic amount of nesting (for nearly endless scaling), implementing a nested set would be the way to go.