I\'ve got a sort of tree like thing going on in my MySQL database.
I have a database that has categories, and each category has a subcat. I\'m keeping all the catego
I would like to share my idea with you.
Limitation of Adjacency Model: Follow the Managing Hierarchical Data in MySQL As you already described adjacency model has limitation that you have to know the level before you retrieve path.
Use Nested model: But if you convert the data structure your data structure to Nested set model then you can still use the self join to get the tree.
Converting Hierarchical model to Nested model: Now we need a tree travel algorithm to index the nested model. This can be implemented in mysql function (Sorry the conversion needs some algorithm implementation : A tree traversal algorithm. Not sure which one is best fitted).
Thanks :)
You want to be given the parent ID:
So assume you are given
set @parentId = 1 /*toys*/
select
*
from
Items i
inner join Categories c on c.id = i.categoryId
where
c.parentId = @parentId
This will give you the items you want - with one major design flaw: it doesn't handle multiple levels of hierarchical categories.
Let's say you had this Categories table:
*Categories table*
id | name | parentId
1 | Toys | 0
2 | Dolls | 1
3 | Bikes | 1
4 | Models | 2
5 | Act.Fig.| 2
6 | Mountain| 3
7 | BMX | 3
And Items:
*items table*
item | category_id
Barbie | 4
GIJoe | 5
Schwinn| 6
Huffy | 7
The only way to get all the relevant Items is do a self join:
select
*
from
Items i
inner join Categories c on c.id = i.categoryId
inner join Categories c2 on c.parentId = c2.id
where
c2.parentId = @parentId
This pattern is not scalable - since you can have MULTIPLE levels of hierarchy.
One common way to deal with hierarchies is to build a "flattened" table: a row that links each node to ALL it's descendants.
In addition to a Categories table, you build a second table:
*CategoriesFlat table* The Name column is here only for readability
id | name | parentId
1 | Toys | 1
-----------------
2 | Dolls | 1
2 | Dolls | 2
-----------------
4 | Models | 1
4 | Models | 2
4 | Models | 4
5 | Act.Fig.| 1
5 | Act.Fig.| 2
5 | Act.Fig.| 5
-----------------
3 | Bikes | 1
3 | Bikes | 3
-----------------
6 | Mountain| 1
6 | Mountain| 3
6 | Mountain| 6
7 | BMX | 1
7 | BMX | 3
7 | BMX | 7
So you can write:
select
*
from
Items i
inner join CategoriesFlat c on c.id = i.categoryId
where
c.parentId = @parentId
And get ALL the relevant Categories and Items.
Here's a great slideshow about SQL anti-patterns and solutions to them. (Hierarchical data in SQL is an anti-pattern, but don't be disheartened - we all run into this one)