I made a voting system and recorded votes in vote table as a row like this:
post_id | user_id | votes | date
Then, I add this vote to user-meta table which has a structure like this:
user_id | meta_key | meta_value
In this table, giving an user_id with the meta_key of “votes”, I can save or get an array of post_ids as meta_value.
The reason I save one vote in two tables is–
1. Why use the Vote table?
I need to calculate vote_total and vote_popularity across all posts, this is not easy to do if I save it only as an element of an array in the user’s meta table.
2. Why use the user meta table?
I need to check if a user already voted for a post or not. The user meta is cached once set. So, I only need to do a check of in_array($post_id, $my_voted_posts). If without the user-meta table, for each post the user visit, I will have to check the vote table.
Is there a better way?
Although my voting system works fine. But somehow I feel this is not efficient way of doing this. I would like to consult you professionals, to learn how I can improve it for better performance. Thanks!
To start, I think checking the vote table is fine if you have an efficient index. You can use composite indexes to index
post_idanduser_id, which will make a query likeselect * from votes where post_id = X and vote_id = Yfairly performant.There will come a point where you will need to denormalize your data for speed, but I don’t think it should be in the same layer as your normalized data. Perhaps you can use redis / memcache for the user metadata?