Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way to implement upvotes/downvotes on a website?

Tags:

mysql

Alright, so I'm planning on making a website with upvote/downvote functionality. Without getting into too much detail about the rest of the site, users will be able to submit content that can be voted on (similar to reddit in that sense—and in that sense only). The only "accounts" on this website will be for administrators and moderators, which brings me to the main question:

How do I limit votes to one per user per post, as best as possible, without accounts?

The site will also be made using Django and MySQL, which brings me to my second question:

How do I store votes in a MySQL database? Should I store an integer in a field in each post, or should it be a table with one vote per row? My guess is definitely the former, but I've never worked with something like this before, so I just want to make sure.

Could anyone point me in the general direction of how to implement the functionality that I want? I've been thinking about it, and I've thought of methods using session variables, cookies, and/or IP addresses. I know that no solution is perfect without accounts, but I just want something that works well enough to prevent people from spamming votes. I'm clueless, so all help is appreciated.

like image 492
GRardB Avatar asked Oct 21 '11 14:10

GRardB


2 Answers

I would highly recommend to use user accounts to minimize the issues. Using IPAddress is not an easy task. Take the simple example some companies only provide one IPAddress to the outside world. In this case your community will not have a proper distribution and people can question your voting system. But if you decided to go with the user account system, you can follow something like this:

post_table
+------------+------------------+------+-----+---------+----------------+
| Field      | Type             | Null | Key | Default | Extra          |
+------------+------------------+------+-----+---------+----------------+
| postId     | int(10) unsigned | NO   | PRI | NULL    | auto_increment | 
| userId     | int(10) unsigned | NO   | MUL | NULL    |                | 
| postTime   | bigint(20)       | NO   |     | NULL    |                | 
| post       | text             | NO   |     | NULL    |                | 
| upVote     | int(11)          | YES  |     | 0       |                | 
| downVote   | int(11)          | YES  |     | 0       |                | 
+------------+------------------+------+-----+---------+----------------+

user_of_website
+--------------+------------------+------+-----+---------+----------------+
| Field        | Type             | Null | Key | Default | Extra          |
+--------------+------------------+------+-----+---------+----------------+
| userId       | int(10) unsigned | NO   | PRI | NULL    | auto_increment | 
| userName     | varchar(50)      | NO   |     | NULL    |                | 
| numPosts     | int(10) unsigned | NO   |     | 0       |                | 
| postsCount   | int(11)          | NO   |     | 0       |                | 
+--------------+------------------+------+-----+---------+----------------+

Also you can use a different model where you have only one vote column and negative get deduct from the positive.

Hope this will help.

like image 54
add-semi-colons Avatar answered Oct 20 '22 19:10

add-semi-colons


With great difficulty.

The reason most other sites out there that do upvote/downvote-ing use accounts is because there is pretty much no other way to guarantee a user won't be able to vote twice on the same thing.

The information available to you that should "narrow" your scope of whether this user has voted before is:

  • Their IP address
  • Their UA string (can be used to further narrow the field after the first)
  • Any cookies/session data that you have stored on their browser

As you can clearly see, all of this information is subject to change and most of it can be controlled at will by a malicious user. If you want to protect yourself from malicious users, the best way forward is user accounts.

If you just want to protect yourself from legitimate users voting twice, just use IP addresses - they're persistent enough that average users won't be able to vote twice in a short space of time.

I'm sorry I can't be of more assistance, as far as I'm aware this is still one of those Great Unanswered Questions. Lots of people would like to be able to guarantee a visitor is the same or different from the previous visitor they got, for hundreds of different reasons, but it's not possible using current technology.

like image 33
Chris Browne Avatar answered Oct 20 '22 18:10

Chris Browne