I have a table posts with columns post_id, user_id, post.
When a user visits his page, I retrieve a list of his posts (select post from posts where user_id=$uid). He can then add one or more posts to the table through a form.
Is there any way I can retrieve these newly-added posts without querying the entire table again?
I'm particularly interested in using this with jQuery to auto-refresh his posts periodically (like YouTube comments when 'auto-refresh' is selected, for example).
Thanks, Albert
If I were you, I would keep track of when the posts were made, e.g.
post_id, user_id, post, made
You can use AJAX to ping a script to check for posts made since the last ping~
query you db like this:
"select * post from posts where user_id=$uid order by post_id desc limit 0,20"
this will get the most recent 20 posts.
Assuming the 'post_id' field is an auto increment int, you can keep track of the largest value ID when you first load the page. For subsequent jquery ajax requests, just do a
SELECT * FROM posts WHERE user_id = '{$user_id}' AND post_id > '{$last_id}' ORDER BY post_id ASC
If the user is submitting posts on the same page that you want to update, why not just update the page as soon as the post is successfully submitted (via ajax)? You avoid re-fetching information you already know, and you avoid re-querying the database all together.
You would dynamically add a post to the page as it is submitted.
function onPostSubmitted(post){
// AJAX submit of the post
$("#posts").prepend( $("<div />").text( postData ) );
}
Related
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.
I am new to MySQL and PHP. I am having issues wrapping my mind around how to accomplish something. I am building a site that has basically a forum style post page. Users enter text into a textarea which then posts that text along with a timestamp and $_SESSION['Username'] into a MySQL table titled "campaigns." So the table has postEntry, postName and postDate rows currently.
On this same page that I have the form, I then display the entire contents of the campaigns table into a div. So it can show each post in descending order.
This has been working great for me, but I am now trying to look at the bigger picture and am thinking this is not a good way to do what I need. I basically need the ability to have an endless amount of "campaigns" each with their own set of posts. Then give the user the ability to select which campaign they want to view and show corresponding posts for that campaign in the div.
So the real question is: Is there a way to do this with just one table. Or would each campaign need it's own table in the database?
Add a campaign_id to the POST table and viola!
edit: more info:
you need one table for the campaign like so:
Campaign
-------------
campaign_id
name
then you need another one for all the posts
post
-------------
post_id
campaign_id
post_time
name
this way, each post is associated to a specific named campaign.
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!
I'm trying to create a blog system with php and I need a way of counting the most viewed post during the last 21 days. Does anybody know of a good way of doing this?
I don't have much experience with php so i need someone to point me in the right direction. I have tried to look into google anlytics API but it seems a bit complicated. Would it be easier to just use cookies?
Since you are building your own blog system, here is the simplest way to do it:
I assume that this is anonymous counting of your blog post visits. If you want to have ip logged records you'll have to adjust the business logic.
Create a new table called visits.
Add an id (Primary key), a field called blogpostid ( that will store the id of the post being viewed) and a field called dtpost with timestamp or datetime properties that upon insert will automatically put the date/time.
Now you can query like this:
select visits.blogpostid, count(dtpost) as counted from posts
left join posts on posts.id = visits.blogpostid
where dtpost between (NOW() AND <-21 days interval function>)
order by counted DESC group by visits.blogpostid;
What you really do is storing the datetime of someone visiting your blog post. This automatically is a count so whatever interval you put the between will fetch the data *. Then the count() function does the counting.
One thing to know is that your own browser refresh will add up to the counting of the visits so you'll have to provide a way to block counting the refresh of the browser (usually a time limit or a cookie to say that you have already seen that page).
*Edit:
Since this is ambiguous, what I mean is that it will fetch your data within the time period that you want.
Create a table views with a foreign key to post ids and add an entry with the visitors information and the date. Then you can fetch the most viewed posts like this (untested):
SELECT p.*, COUNT(p.*) count FROM posts p
INNER JOIN views v ON v.post_id = p.id
WHERE DATE_SUB(CURDATE(), INTERVAL 21 DAY) <= p.date_viewed
ORDER BY count DESC
GROUP BY p.id;
To prevent the count from incrementing when viewed multiple times by the same user you can use the session meganism to prevent that from happening.
session_start();
if (!isset($_SESSION['posts_viewed'])) {
$_SESSION['posts_viewed'] = array();
}
// some logic to get to relevant post id here
// check that the post_id is not in the array
if (!in_array($post_id, $_SESSION['posts_viewed'])) {
// logic to increment a persistent counter (e.g. in mysql) here
// add post_id to array
array_push($_SESSION['posts_viewed'], $post_id);
}
// finally some logic that display the post here
session_close();
I'm currently making my own social network and I have a php problem which I do not know how to solve.
So my aim is to display the posts made by the user himself and his friends whereas if you weren't their friends, their posts would be hidden to you.
I have done many research trying to find the answer aswell as implementing the answers but nothing seems to work for my script.
So, here's what my table looks like:
users: key, id, fullname, username etc...
posts: id, feedusername, author, feedpost
shares(AKA friends): id, userId1, userId2, status
At the moment, I am displaying the posts with a while loop.
while($feedarray = mysql_fetch_array($search)) {
*I pull the users post data here by using that fetch_array function and echo them out*
}
And the $search SQL code is this:
$search = mysql_query("SELECT * FROM posts ORDER BY id DESC LIMIT 0,20");
At the moment, this displays all of the posts regardless if you're friends or not friends with that user. Which is not what I want.
So, how do I display my own posts and my friends posts? And if your not friends with lets say, "a", then how do you not display the post's made by "a" to that user who isn't friends with "a"?
In other words, if chaotic(userId1) is friends with max(userId2) and their status is equal to 2(if status is equal to 2, then they are friends. If it's 1, the friend request is pending.)
How do I display my own posts(chaotic's posts) and Max's posts? Whereas If this record does not exist or status is equal to 1, I wouldn't be able to see Max's posts.
Hope you understand what i'm saying and thank you for your time.
Thanks!
ChaoticS
So from what you're saying I gather getting your own posts would involve something like:
SELECT *
FROM posts
WHERE author = #MyUserId
So, given we now want friends, think of how you retrieve friends. It's going to be something like:
SELECT userid2
FROM shares
WHERE userid1 = #MyUserId
AND status = 2
(And may have to make another query reversing the userid1/userd2 columns, depending how your table is setup). So, given that, it's a matter of combining the two forms:
SELECT *
FROM posts
WHERE author = #MyUserID
OR author IN (
SELECT userid2
FROM shares
WHERE userid1 = #MyUserId
AND status = 2
)
You can keep expanding on how you use sub-selects, etc. to be more inclusive/exclusive, but I'll leave that up to you. If you're still having trouble leave me a comment and I'll do my best to help.