I have a post voting system that stores and displays the vote as an integer. When someone clicks on plus the vote increases by 1, when minus - decreases by 1 (exactly the same way as on this website). The problem is that the votes are cookies-based, so when these are refreshed the user can vote again. I would like to limit this to just one vote per user.

Now I would like to ask for advice regarding the database design. Currently I have my custom post type 'Question' and standard WordPress user tables in the database. Question has a custom field called vote that stores the vote as a single integer. The goal is to be able to assign a vote to question in a way that I can print all the users that voted on a particular question or check if user already voted on a particular question.

Should I create another table with votes? Or add a new field in Question or Users? I am not sure about the database logic that I should implement so I would appreciate any advice.


I would modify your design a bit so you can leverage the data as well prevent logic mistakes that may ruin your stats.

First I would store up and down votes as two separate meta values. The reason is that you can then display both if you desire, as well as calculate votes as a percentage of the whole. For example 45 up, 10 down, or 81% favor this question, and 55 people have voted. You can then show those stats to the users. How you do it now can only show a net positive gain which gives no context to actual popularity, i.e +3 is not that useful.

Logic mistake prevention: If your code does +1 or -1 and your code has bad logic then all your votes will be wrong potentially. It is easier to simply store the votes as the user intended and then use retrieval/read techniques to then do your logic. i.e to keep data integrity you never want to write destructive logic. It is easier to fix a read error 45up/55total than to modify "vote" by a set of writes. How can you fix data that you have overwritten is my point.

A cookie is good to prevent several requests in a session but the best way to track a user with or without a cookie would be to use ajax and after they try voting on a question lookup the users vote for the current question (assuming no cookie was set or it expired). By doing this you could also allow them to change their vote. This would mean you would need to do one of two things that I think could be easy:

Have a logging table of how a user voted that tracks their username/user_id, the question number, and their vote. This would be a standard non wordpress way in pure mysql systems but might also make sense for you here. The other option might be to serialize a users votes across all questions answered and store as one object. Now since your info is brief about your system its hard to give a definitive answer to whats best; whether to use another table or serialize a meta field in the meta table. This should give you some ideas.

  • updated answer to talk about logic mistakes. – Shawn Feb 3 '15 at 19:16
  • 1
    if you serialize the data, you can't query on who voted on a particular question. – Milo Feb 3 '15 at 20:16
  • That is a good point @Milo. I was thinking each user might have their own "history" sort to speak and he would deserialize on the fly. i.e user history for user_id 12 and then deserialize it. – Shawn Feb 3 '15 at 20:31
  • Thank you Shawn for your detailed answer. You are right regarding the design, however I am trying to modify an exisitng theme - 2code.info/demo/themes/ask-me . When you click on each question you can see thumbs up and down. Based on that I select the most popular questions, so your solution in this case is not optimal. I thought I will just create a new table called Votes with fields such as PostID and Author. Then when I want to print all people that voted I would execute SELECT author where PostId = myPostID. Does this make sense in your opinion? – Vonder Feb 4 '15 at 17:57
  • You can add another table which is not necessarily bad, but then you do surrender that you can't use the wordpress loop in the same manner. Is there no good way to add these as custom meta fields to each question? Then you can use a subloop to look up all the people that voted? – Shawn Feb 4 '15 at 21:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.