The most efficient method storing voting data in a MySQL database (like StackOverflow)
-
27-03-2021 - |
Вопрос
I'm trying to replicate SE's voting system. User's on my website should only be able to vote on posts one time, then they are locked in. I currently have two tables, users
and posts
.
How should I store information on which posts a user has voted on? I was thinking of having a column in posts
which would store the uid
s of users which have voted on it. Another idea would have a column in users
with the id
s of the posts he/she has voted on.
How should I do this? I want to take scalability into account and easy of determining whether or not the vote is valid.
Решение
Create another table to store information from the users
and posts
tables:
CREATE TABLE votes (
user_id INT
, post_id INT
, PRIMARY KEY (user_id, post_id)
);
With this approach:
I was thinking of having a column in posts which would store the uids of users which have voted on it. Another idea would have a column in users with the ids of the posts he/she has voted on.
Unless you store the values as delimited values (to fit in one cell) or JSON, you'll end up with many rows for just one post. But then, that's a bad approach to start with.
Stick with creating a new table which contains the relationship determining "voting". The table is simple enough to check:
SELECT COUNT(t1.post_id) AS vote_count
FROM votes AS t1
WHERE
t1.user_id = SOME_INTEGER
AND t1.post_id = SOME_INTEGER
Другие советы
Best practice, for something the size of stackoverflow, is to store the individual votes in a separate table. But also keep a derived vote count in a field directly attached to the post. As database sizes grow, it'll become prohibitively expensive to sum up all the votes on every viewing of a post.
Keeping this derived field is relatively easy by use of triggers on this user/votes table.