views:

486

answers:

3

I'm working on a PHP app that has several objects that can be commented on. Each comment can be voted on, with users being able to give it +1 or -1 (like Digg or Reddit). Right now I'm planning on having a 'votes' table that has carries user_id and their vote info, which seems to work fine.

The thing is, each object has hundreds of comments that are stored in a separate comments table. After I load the comments, I'm having to tally the votes and then individually check each vote against the user to make sure they can only vote once. This works but just seems really database intensive - a lot of queries for just the comments.

Is there a simpler method of doing this that is less DB intensive? Is my current database structure the best way to go?

To be clearer about current database structure:

Comments table:

  • user_id
  • object_id
  • total_votes

Votes table:

  • comment_id
  • user_id
  • vote

End Goal:

  • Allow user to vote only once on each comment with least # of MySQL queries (each object has multiple comments)
+5  A: 
That helps a lot actually, thanks! That thought about having two primary keys didn't even cross my mind..
mdolon
A: 

Why don't you save the totaled votes for every comment? Increment/decrement this when a new vote has happened.

Then you have to check if the user has voted specifically for this comment to allow only one vote per comment per user.

ByteNirvana
The trick is the second part, checking if a user has voted for that specific comment - it basically leads to having a separate vote table.
mdolon
A: 

You can put a sql join condition which returns all the votes on comments made by the current user for this object, if you get no rows, the user hasn't voted. That is just slightly different from you checking each comment one by one in the program.

as far as the database structure is concerned, keeping these things separate seems perfectly logical. vote { user_id, object_id, object_type, vote_info...)

You may be already doing this, sorry but I couldn't interpret from you post if that was the case.