php and mysql site design question - php

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 :)

Related

Mysql keep track of users views for each post in timelime

I have a screen that looks very much like facebook timeline
users can view posts of other users etc.
to get these posts i do something like
select user.id,user.name,posts.title,posts.body from posts left join users;
now data i need to collect is "Who saw this post" .
is there any elegant way to do it ?
right now all what i can think of is every time i fetch posts. i loop over them, then collect all ids of posts that the query returned and then push in another table
user_views [pk:user_id+postId]
userId,postId
1 , 1
Then when i'm fetching posts next time i can do count of user_views.
select *,count(user_views.id) from posts join user_views on post_id = post.id
but this sound like a lot of work for each VIEW, specially that most probably user will see a most multiple times,
is there any known patterns for such need ?
This is a design question and the answer really depends on your needs.
If you want to know exactly who viewed what post and how many times, then you need to collect the data on user - post level.
However, you may decide that you do not really care who viewed which post how many times, you just want to know how many times a post was viewed. In this case you may only have a table with post id and view count fields and you just increment the view count every time a post is being viewed.
Obviously, you can apply a mixed approach and have a detailed user - post table (perhaps even with timestamp) and have an aggregate table with post id and view count fields. The detailed table can be used to analyse your user's behaviour in a greater detail, or present them a track of their own activities, while your aggretage table can be used to quickly fetch overall view counts for a post. The aggregate table can be updated by a trigger.

Rerequesting posts from mysql database social network site

I am working on a social network website project. I have created database and everything.
The posts table has a preference column which stores the preference value according to the likes and comments that a post gets from the users and also the time at which the post is created.
To retrieve posts for a user's home page from the posts table, I am running a query using joins which sorts using preference column .
Now, suppose I retrieve 10 posts for a user to be shown on the posts table and user scrolls down and one more request is made from the user to retrieve next 10 posts to the server.
If in between of those requests few other users creates a new post or preference value of posts in the database changes in the between, and now if I the second request is run on the server, all the posts will be resorted for the second request (i.e. to show next 10 posts) but since the database is updated , this means in the second request there will be many chances that few of earlier 10 posts are retrieved along in the second request.
I want to know how to avoid these duplicate requests.
How facebook or any other social network solves this problem at the backend when their database is dynamic.
I would rather avoid such unreliable way of sorting at all.
As a user, I'd rather quit that service. Frankly, I hate such too smart a service which decides which posts I have to see and which not. And even dynamically ordered on top of that.
Make it ordered by date, by tags of interest, by something sensible, reliable and constant.
In your script store a record of the rows id returned.
For example, using a basic limit and just storing the latest id when the first select is done, and using the page number to determine the limit of records to return.
SELECT id, somefield
FROM SomeTable
WHERE id < $SOMESTOREDVALUE
LIMIT $PAGENUMBERTIMESTEN, 10
or storing the latest id after each page is returned (which you will need to store each time this is run)
SELECT id, somefield
FROM SomeTable
WHERE id < $SOMESTOREDVALUE
LIMIT 0, 10
If you store the time & date when the user first makes a request in a session, you could use that to filter the posts table.
So your SQL for the second page of results would be along the lines of
SELECT <some fields> FROM <sometables>
WHERE DatePosted <= $timefirstseen LIMIT 10, 10
Where $timefirstseen was loaded from the session variable. This will restrict your results to only posts that existed when the users visit started.
You would of course need to include a feature to allow the user to clear the session or do that automatically when they revisit their homepage to make sure they got to see the new posts eventually!

how to stop people giving a thumbs up twice on a web page

im making a site thats a news/blog kind of site where people can leave comments to the posts that are made. then logged in users are able to give a comment a thumb up or down. it works fine at the moment i click the thumb and it uses ajax to add the count to the database and update the number and it also stops the person from being able to click the thumb again but if you press f5 to refresh the page you can click the thumb up again. how can i stop this from happening?
adding this to a database is an option i was thinking of but the site needs to be able to handle lots of comments and users there could be thousands of thumbs made to comments since its an easy action to perform the database table would be huge after a short amount of time which would surely slow down page loads since it will be querying a massively long table every time you view a page with comments.
currently i keep count of the thumbs up and down in the comment table so it querys the comments table and will display the numbers. are you suggesting i add a new table that contains userid and a commentid if someone makes a thumb up so i can query that table and if there is a row where userid == the logged in user and commentid == the comment dont allow? if so this is the thought i had on how to do it but as i said above it will lead to a massive table that will surely slow down the loading of the page
One way to go is when you load the comments also load if that user has already casted a vote on each of them, disable the thumb up button if that user already voted.
You shouldnt store the click as a simple counter but store the actual event
Create a seperate table called 'clicklog' or something and add the fields like userid, commentid, IsThumbsUp. Then in your ajax page you can add the thumbs up to this table (IsThumbsUp is a boolean. True for thumbsup and false for thumbs down.
then instead of using something like SELECT comment, thumbsUp, thumbsDown you could use
SELECT id, comment,
(SELECT count(commentid) FROM clicklog WHERE commentID=id AND IsThumbsUp=1) AS thumbsUp,
(SELECT count(commentid) FROM clicklog WHERE commentID=id AND IsThumbsUp=0) AS thumbsDown
FROM comments
And also in your AJAX page you can check if the user has voted before. If he has, dont allow it. Or even better. When he has voted UP, he can change it to vote DOWN (change the IsThumbsUp from 1 to 0) or visa versa.
Just make sure each user only has one connection with commentid and userid.
Also make sure you put an index on the fields in clicklog to get the information quickly. I'd put the primary key on commentid and userid combined and then a seperate index on commentid and IsThumbsUp combined

Thumb rating for wordpress - top user

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.

MySQL Table structure of thumb UP & DOWN for comments system?

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.

Categories