Reputation:
To be clear, I'm not looking for someone to design an entire forum here, rather, I need some help determining how to relate a couple of tables, and whether or not these tables need to exist in the first place.
Basics of a forum
Topics
topic_id // Unique topic ID, AI, PK topic_name // name of the topic ... etc
Users
user_id // Unique ID of the user, PK, AI user_name user_pass user_email user_date
Posts
post_id // unique ID of post - PK, AI post_content ... etc
I also want to include the ability to like / dislike a post, and for that reason I created a table post_ranking
which looks as follows
id // Auto increment ID post_id // Foreign key, refers to post.post_id user_id // Foreign key, refers to user.user_id vote_up // Whether or not the post was voted up (0 for down, 1 for up) rank_date // date the ranking occured
The problem I've just run into is that I cannot figure out how to incorporate the replies into this table. The only option I've thought of so far would be to create a second table called reply_ranking
- but wouldn't this be somewhat unorganized?
So, my question:
Should I create two separate tables for rankings (post_ranking
, reply_ranking
) or is there another way that I should be arranging the tables above which would avoid this problem in the first place?
Upvotes: 0
Views: 1089
Reputation: 2552
Your post is not very clear, I can't understand if in the table Topics you have inside also posts in that topic and replies to that topic.
In this case I think that this is not the good way, you should have posts separated from topic data. Let me explain.
A forum is formed by:
// MAIN PAGE, showing avaible forums
// |
// SPECIFIC FORUM, that show the threads (or topics) inside
// |
// POSTS that show part of the post related to that thread.
//
// USER_CP -------------- ADMIN_CP
We need at least 4 tables (I'm not considering admin_cp). these are:
// TOPICS:
// +---------------+---------+-------------+----------+----------+----------------+
// | ID, p.k. a.i. | TITLE | SUB_TITLE | AUTHOR | CLOSED | PARENT FORUM |
// +---------------+---------+-------------+----------+----------+----------------+
//
// These are very few basic field for the table. No reference about the posts here.
//
//
// FORUMS:
// +---------------+---------+-------------+--------------+
// | ID, p.k. a.i. | TITLE | SUB_TITLE | VISIBILITY |
// +---------------+---------+-------------+--------------+
//
// Almost clear, visibility is a value to determine if the forum is private (such are
// forums like: "Moderator rooms" or "Admin stuff"), protected (i.e. for non registered
// users, or if the forum is public.
//
//
// POSTS:
// +---------------+----------+-------+-----------+--------+---------+-------+- - -
// | ID, p.k. a.i. | TOPIC_ID | TITLE | SUB_TITLE | AUTHOR | MESSAGE | VOTES | ...
// +---------------+----------+-------+-----------+--------+---------+-------+- - -
//
// In Votes you have a integer number (positive o negative, no matter) with the total
// of the votes for this post (not useful if you fully use the table like).
//
// REPLIES
// +---------------+----------+---------+--------+---------+
// | ID, p.k. a.i. | TOPIC_ID | POST_ID | AUTHOR | MESSAGE |
// +---------------+----------+---------+--------+---------+
//
//
// USERS
// +---------------+------+------+------------+------+---------+- - - - -
// | ID, p.k. a.i. | NICK | PASS | PRIVILEGES | NAME | SURNAME | ETC..
// +---------------+------+------+------------+------+---------+- - - - -
//
// Privileges determinate if a user is admin, mod, super_mod or simple user
//
//
// LIKES
// +---------------+---------+---------+----------+----------+---------+------+
// | ID, p.k. a.i. | USER_ID | POST_ID | TOPIC_ID | REPLY_ID | UP_DOWN | DATE |
// +---------------+---------+---------+----------+----------+---------+------+
This is, in my opinion the structure you should use.
home page, show all the forums:
WHERE visibility >= user_privileges
Forum page, show all the topics (and moderators):
WHERE parent_forum = forum_id
Topic page, show all the messages.
WHERE topic_id = current_topic_id
WHERE post_id = selected_post
User page:
WHERE id = user_id_that_want
WHERE user_id = actual_user
With this table structure you can also use a StackOverflow similar way to consider votes, i.e. UPvotes are 0 for the voter, but downvote are -1 for the voter. For each post, you can read from the like table just using post_id, so you know how many votes have the post (up and down) and with this you can count also up vote +10 to the post creator, downvote -5 to post creator.
Only with an extra table that is likes.
You can have:
When you insert a topic you will add:
user_id
topic_id = topic id
post_id = -1 (this is not a post, is the topic!)
repl
y_id = -1 (as above)
when you insert a post:
user_id
topic_id = current topic
post_id = post_id
reply_id = -1 (this is not a a reply)
when you insert a reply
user_id
topic_id = current topic
post_id = current post
reply_id = the reply id.
This will not have id problem issues. because the three are separated.
If you call for all the answer of a specific topic and a specific post you will add:
WHERE topic_id = current, post_id = current
if you need the reply of a topic, just put post_id = -1
And so on. No issues with the ids!
I think I have explained almost all. for any question, ask! EDITED: something here and there
Upvotes: 1
Reputation:
Another thing you can do is make a single rankings table, with a field indicating whether the upvote/downvote is for a post or a ranking. You will have to use a non unique generic "item_id" instead of post id or reply id, but you do get one table if this is important to you.
EDIT: Just realised the foreign key field will be non unique anyway, since you may have multiple votes for the same post; the point is post ids and reply ids can't be told apart.
This WILL make it harder to deal with querying the table. My recommendation is you go with your current plan and make two tables; it is the most semantic way you can organise your data.
Upvotes: 0
Reputation: 11897
I usually think like this:
One user has many posts (this means you'll need a users
table and a posts
table, and every post will have a user_id to signal who owns it.
For some relations, (for example, when you realize that A has many B and B has many A, that's what we can an n to n relationship), you'll need a third table; this might be what you are hinting at in your comment as to what the reply entity should be translated to in your database....
Feel free to commit errors... almost never you will end up with the exact same model you started with... many things we don't know we need until we do.
Upvotes: 0