i already created a table for comments but i want to add the feature of thumb Up and Down for comments like Digg and Youtube, i use php & mysql and i'm wondering What's the best table scheme to implement that so comments with many likes will be on the top.
This is my current comments table : comments(id,user,article,comment,stamp)
Note: Only registred will be able to vote so it should limit 1 vote to each user in a comment
Thanks
Keep a votes table. E.g. votes(comment_id, user_id, value, stamp) - value is -1 or +1.
This allows accountability, and you can do a UNIQUE index on (comment_id, user_id) to prevent duplicate voting. You can also remove a user and all of his votes easily, if he/she is spamming.
For sorting comments by score it is possible to do a JOIN between the comment and vote tables and use SUM/GROUP BY to get the total score. However, this can be slow. For speed, you might consider keeping a score field in the comments table as well. Every time a new row is added to the votes table, you add/subtract 1 from the comment's score.
Because you are storing every vote in a table, it is easy to recalculate the score on demand. Stack Overflow does something similar with reputation - the total reputation score for a user is cached and recalculated every so often.
You could add a score field and increment or decrement with each thumb action:
UPDATE comments SET score=score+1 Where id=123
Then when you select, order by score DESC.
Since a user should be registered to thumb up/down, I would store the user ID and the post ID to validate the up/downs.
2 tables will be appropriate for this task. Let me know if you need a design.
Related
So I have two different tables, a users table and an articles table. The idea is to allow a user to rate an article, but only allow them to rate it once (possible change their existing rating too but I can come to that conclusion later).
As of now I just have the update value working to allow them to rate the article, but of course a user can rate an article as many times as they want.
To give you an idea of how I have everything working, when a user logins in, a session is created with their user information. So when they go to rate an article, I have the ability to check the user, I just don't know how to stop them from rating if they have already rated a specific article.
The user table consists of among other things their username and their unique ID
and the article table consists among other things the article contents, the article unique ID, and the articles rating.
I had some really sloppy ideas like when the user rates an article their ID gets stored into the articles row in some kind of "users who have rated" column, and then I can do a for loop or something to siphon out all the user IDs and then check if their ID exists in that articles entry but then each article would have a row with possibly hundreds or thousands of userIDs on it and there seems like there would be a more elegant way.
Any help or direction is appreciated :)
Create a UserRatings table which has foreign keys to the users table and the articles table, and stores a row linking the user to the article, and the rating they gave it and when it occurred.
Then if a user tried to rate it again you just check this table for the user ID/article ID combination before allowing it.
And then if you wanted got can do things like show the user a list of articles they have previously rated, etc
I'm trying to create a filter to show certain records that are considered 'trending'. So the idea is to select records that are voted heavily upon but not list them in descending order from most voted to least voted. This is so a user can browse and have a chance to see all links, not just the ones that are at the top. What do you recommend would be the best way to do this? I'm lost as to how I would create a random assortment of trending links, but not have them repeat as a user goes from page to page. Any suggestions? Let me know if any of this is unclear, thanks!
This response assumes you are tracking up votes in a child table on a per row basis for each vote, rather than just +1'ing a counter on the specific item.
Determine the time frame you care about the trending topics. Maybe 1 hour would be good?
Then run a query to determine which item has the highest number of votes in the last hour. Order by this count and you will have a continually updating most upvoted list of items.
SELECT items.name, item_votes.item_count FROM items
INNER JOIN
(
SELECT item_id, COUNT(item_id) AS item_count
FROM item_votes
WHERE date >= dateAdd(hh, -1, getDate()) AND
## only count upvotes, not downvotes
item_vote > 0
group by item_id
) AS item_votes ON item_votes.item_id = items.item_id
ORDER BY item_votes.item_count DESC
You're mentioning that you don't want to repeat items over several pages which means that you can't get random ordering per request. You'll instead need to retrieve the items, order them, and persist them in either a server-wide or session-specific cache.
A server-wide cache would need to be updated every once in a while, a time interval you'll need to define. Users switching page when this update occurs will see their items scrambled.
A session-specific cache would maintain the items as long as the user browses your website, which means that the items would be outdated if your users never leave. Once again, you'll need to determine a time interval to enforce updates.
I'm thinking that you need a versioned list. You could do the server-wide cache solution, and give it an version (date, integer, anything). You need pass this version around when browsing the latest trends, and the user will keep viewing the same list. Clicking on the Trends menu link will send them to the browsing pages without version information, which should grab the latest from your cache. You then keep this as long as the user is browsing these pages.
I can't get into sql statements, not because they are hard, but we don't know your database structure. Do you keep track of individual votes in a separate table? Are they just aggregated into a single column?
Maybe create a new column to record how many views it has? Then update it every time someone views it and order by threads with the largest number of views.
I am currently using gd star rating (thumb rating) to rate posts (articles - no rating on comments). What I really want to do is show a table of the top 5 users and their number of votes based on the total number of thumbs up they get for all their posts. For instance
| user | No of votes |
If this is not possible with this plugin, is there any other plugin that is capable of such. Or is there a manual way of achieving what I want. I don't mind manual coding with the right nudge.
Many thanks guys
The easiest way to answer your question is to look at the database and see how the plugin is storing the "votes". I don't know that plugin, but it has to track the up/down votes somewhere, either in it's own table, or by adding a column to one of the default WP tables.
Once you track down the table that's tracking the votes, you can write a basic query that returns a limited set of users, ordered by their up/down votes. It'll look something like this:
$wpdb->get_results("SELECT id, name FROM up_down_votes_table ORDER BY what_ever_the_column is named");
The full documentation for querying the database is here.
I need to set up a simple voting system for my application., My application consists of articles posted as well as comments. I would like to add voting abilities to both articles and comments and at the same time be able to sort comments based upon highest voted etc.
I have the following restrictions i.e since the application needs users to log in - only logged in users can vote, secondly a user can vote on an item only once. Users can upvote or downvote or cancel a vote they've made.
What would be a decent table design for this, plus I need the solution to be scaleable. Thanks for the advice
I think I would go with a join-table between the users and articles tables :
users_articles
- article_id
- user_id
- score
- date
With the following notes :
article_id is a foreign key to the article that gets up/down-voted
user_id is a foreign key to the user that voted
score is +1 or -1 depending on the vote
the primary key is on the two article_id, user_id columns.
a user voting on an article means inserting one line in this table ; canceling the vote means deleting that line (or setting a 0 score if you want to keep track of the fact the user has voted)
That's for votes on articles.
And I would do another users_comments table for the votes on comments.
I am trying to build a website with mysql and php. This is the first site I have attempted so I want to write a little plan and get some feedback.
The site allows users to add some text in a text field as a “comment”. Once the comment has been entered into the site it is added to the database where it can be voted for by other users.
When a new comment has been added to the database it needs to create a new page, e.g. www.xxxxx.com/commentname or www.xxxxxx.com/?id=99981.
There will be a list of "Comments" in the database along with the number of votes for each comment.
The home page will have two functions.
1) Allow users to add a "comment"
2) Display two tables, each with 20 rows containing most "popular comments" and "recent comments"
Each comment will generate its one page where the comment will be displayed. Here users can read the comment and Vote for the comment if they wish.
Please help me out by explaining how to do the following.
-Generate a new page whenever a comment is added to the database
-Add a vote to the vote count in the comment database.
-Display the top 20 most popular comments as per number of votes.
-Generate a new page whenever a comment is added to the database
You only need a comment.php file with a MySQL query getting the given comment out of the database. I would recommend to use the comments primary key to get the comment. Using rewrites you can have a URL like this: www.xxxx.com/comment/1. If you need the redirect for a specific link structure ask again.
-Add a vote to the vote count in the comment database.
Just add a column to your table holding the votes. If you have logged in users and you want then to check their votes, create a new table for the votes and another table for the many to many realtion.
-Display the top 20 most popular comments as per number of votes.
This is simply done by sorting in the MySQL queries and selecting only 20 results:
// For the recent 20 comments
SELECT * FROM comments ORDER BY id DESC LIMIT 0,20
// For the 20 most popular comments
SELECT * FROM comments ORDER BY votes DESC LIMIT 0,20
Any further questions?
This is a pretty broad question, i don't think we'll be able to help you fully here at stack without making a full blown php blog tutorial!
I'll try and point you in the right direction however. Firstly i'd say take a look at wordpress, even though i presume you want to make your own custom one, wordpress would be a good starting point for code inspiration? (Just a thought)
The way i'd generate a new page, would be to make a php page, say comments.php, which using the $_GET variable, gets the related record in the database and displays it.
Adding a vote up or down is as simple as adding form to the page with two submit buttons, one with a value of 1 one with a value of -1, upon submit it sends its value to the database, and takes the existing vote value say 25 and adds its value so, if u up voted 25 + 1 = 26 if you downvoted 25 + -1 = 24.
Displaying the 20 most popular comments is just a case of using some SQL sorting, something like this would work
SELECT * FROM comments ORDER BY votes DESC LIMIT 0, 20
That statement selects all the columns from the comments table, sorts it by the votes column decending, so highest value first, and then limits the number of records it fetches by 20, from there its a case of looping through each record and displaying it how you wish.
I hope this atleast gets you started on the right path :)