Are having TRIGGERs for every upvote/downvote detrimental in terms of performance?
Question
I plan to have three tables: Users
, User_Reputation
and Voting_Records
. The Users
table would hold the primary key id
for the registered users, along with personal information such as email and passwords. If they upvote something, it would record it in the Voting_Records like so:
+------+-------------+-----------+--------+
| id | user_id | author_id | vote |
+------+-------------+-----------+--------+
| 3 | 12389129 | 123421 | -1 |
+------+-------------+-----------+--------+
With the user_id
and author_id
being a foreign key to the id
of the Users table, this would subtract 1 from the overall reputation.
So instead of using SUM()
for every time a user queries for a total of their reputation, would it be more beneficial to have TRIGGER
to update the total_votes
on the User_Reputation
table every time someone upvotes/downvotes on their profile? It would definitely be more easy to implement features such as badges, which would be automatically awarded to people with more than X points.
Solution
This is called an aggregate table. This is a valid strategy.
You could also defer the calculation of user reputation if you are not bothered with real-time updates. Some sites do DB maintenance during the night, rebuild indexes etc. Since we are talking about user reputation, it's no big deal if the current stats are only reflected the day after. I don't think people will even notice.
User_Reputation
could be a field in your table Users
. It is simply an integer value that is incremented or decremented when an upvote or downvote is recorded. If you are writing more than one records, then wrap it up in a transaction:
- Add a record in
Voting_Records
- Update table
users
: increment/decrement the value ofUser_Reputation
It doesn't have to be a trigger, it could be a standalone SQL statement or a block of code in a stored procedure, as long as there is a transaction to ensure consistency and as mentioned above, you have to consider concurrent updates.
You can even make the DB read-only for a short while when maintenance is in progress, I think that's what Stack Exchange does (sometimes).