I wanted to ask if there is a way to better handle hierarchical data in mysql
than what I have set up currently.
In my mysql
database I am storing a shallow hierarchy for a forum:
Titles(0) > Boards(1) > Threads(2) > Comments(3) type(0, 1, 2, 3)
The hierarchy is represented as follows:
Table 1: posts.title, posts.id, posts.type
post.title(title is the data within the post)
post.id(id is the primary key of the post)
post.type((what level)/(how deep) the post is in the hierarchy)
Table 2: parent_tree=(pt) pt.child, pt.parent
pt.child (primary key of a post)
pt.parent (primary key of post which is a parent of the child post)
Each post has a self referential parent_tree entry (ex: creating new post which has id=7
results in parent_tree
a new entry where child is 7
and parent is 7
:
Each post upon being created also copies all PARENTS
of the parent it is being created under (which would also include its self reference).
Inserting (POST
) is simple. Upon a new post being created, two queries are made - one for inserting the new post, the second for inserting its parent_tree counterpart, which sets child as a the foreign key (with ON DELETE CASCADE
).
Getting (GET
) is simple, a user can select a post by id
/title
and type
.
Deleting (DELETE
) is simple, a post selected by id
/title
and type
is deleted (and thus its foreign key parent_tree entry).
Moving (PUT
) is the most complicated of the bunch, it consists of two queries.
In this action, a post is selected (title
/id
) and a (parent_title
/parent_id
) to specify what parent
it is being moved to be under.
First query - select all parent_tree
entries where parent id = the id of the post about to be moved, select all parent_tree
entries where child is the result of the previous selection, which returns all children of the post to be moved as well as all of their parents. Then, from this selection delete all parents, child pairs where the parent is also a parent of the selected post
(short) delete entries in parent_tree
of post and its children where the parent has the post as a child.
Second query - Insert into the children of the post that is being moved, and the post itself, all parents of the new parent (which includes a self reference) the selected post is being appended under.
Here is how i do my queries in mysql
for the moving (completely open to suggestions, I am relatively new to mysql
and learning).
First query:
DELETE t FROM parent_tree AS t INNER JOIN parent_tree AS c ON t.child=c.child INNER JOIN parent_tree AS p ON t.parent=p.parent WHERE c.parent IN (SELECT id FROM posts WHERE title=?) AND p.child<>p.parent AND p.child IN (SELECT id FROM posts WHERE title=?)
?[0,1] = title_of_post_being_moved
Second query:
INSERT INTO parent_tree(child,parent) (SELECT t.child, p.parent FROM parent_tree AS t INNER JOIN parent_tree AS p WHERE t.parent IN (SELECT id FROM posts WHERE title=?) AND p.child IN (SELECT id FROM posts WHERE title=?) AND t.child<>p.parent)
?[0] = title_of_post_being_moved, ?[1] = title_of_new_parent_post