Reputation: 119
My post table has the columns: id, user_id, title, message, date
My comment table has the columns: id, user_id, post_id, message, date
Since these 2 tables are so similar, would it be better to have a single table with the columns:
id, user_id, parent_id, type, title, message, date
and every row that is a parent post will have an empty parent_id value and every row that is a child post will have an empty title value. The type will either be 1 for parent posts or 2 for child posts.
Edit: I will also use a rating feature and I ask the same question again, 2 specific post_rating and comment_rating tables, or a generic rating tables. In case of the ratings table, the structure will be exactly the same, so no nullable fields. It's also unlikely that the rating table(s) will change, since it only knows about the owner of the rating, the actual rating, and the targeted post/comment/etc.
Upvotes: 2
Views: 562
Reputation: 3290
I would not do that for a few reasons:
Regaring the rating system: You can just make a normal table with ratings and the comments and posts table will get a FK relationship to the ratings table. Like the one you are having for the user right now. However, you also can make two separate tables, to be more flexible later, and it can make the joins a little bit faster as the rating tables will not get as big. But this is more personal preference than anything else. I would certainly make a separate table if the rating systems will drift from each other, but in this case I also would go for one.
Upvotes: 6
Reputation: 861
Using a single table would allow you to have a deeper nested heirarchy. For example:
title
comment
comment2
comment_to_comment
comment3
comment_to_comment2
comment_to_comment3
So it's an additional capability that doesn't exist with the 2 table setup.
"I would only do it if you need that capability" because the queries will be more complicated. It would also be beneficial to add a (root_id) column to such a table to indicate the node with the title for comments with a nesting level greater than 1.
You could also use one table for the data and one table for the parent/child hierarchy (this is just an example, you may need to adjust the syntax).
create table element (
id serial not null primary key,
data integer not null
);
create table heirarchy (
id serial not null primary key,
id_root integer not null references element(id),
id_parent integer not null references element(id),
id_child integer not null references element(id)
);
insert into element (data) values (100);
insert into element (data) values (101);
insert into element (data) values (102);
insert into element (data) values (103);
insert into element (data) values (104);
insert into element (data) values (105);
insert into element (data) values (106);
insert into element (data) values (107);
insert into element (data) values (108);
select id, data from element;
1 | 100
2 | 101
3 | 102
4 | 103
5 | 104
6 | 105
7 | 106
8 | 107
9 | 108
insert into heirarchy (id_root, id_parent, id_child) values (3, 3, 4);
insert into heirarchy (id_root, id_parent, id_child) values (3, 3, 5);
insert into heirarchy (id_root, id_parent, id_child) values (3, 4, 1);
insert into heirarchy (id_root, id_parent, id_child) values (3, 4, 2);
insert into heirarchy (id_root, id_parent, id_child) values (3, 1, 9);
insert into heirarchy (id_root, id_parent, id_child) values (6, 6, 7);
insert into heirarchy (id_root, id_parent, id_child) values (6, 6, 8);
This kind of thing isn't trivial and you also can setup triggers to prevent circular relationships.
Upvotes: 1