Tom
Tom

Reputation: 4577

Querying data for a Facebook-like news feed

I have a social networking site where users update their moods, profiles and add photos.

I'm currently logging all updates in a table called "update_log" with the following structure:

update_id int (auto), 
userid int, 
update_type int (1=profile, 2=photo, 3=mood)
pictureid int
mood_a int
mood_b int
mood_c int
update_time int

Profile update record: (auto), 1, 1, 0, 0, 0, 0, 1239003781

Photo update record: (auto), 1, 2, 11544, 0, 0, 0, 1239003781

Mood update record: (auto), 1, 3, 0, 1, 490, 70, 1239003781

For the photo record, there's a corresponding table userphotos which holds the caption and filename/location data

For moods, there is a mood lookup table that holds the mood descriptions (i.e., I'm lazy =\ )

What I need to do is query this data to show on a user's profile page, it will show this feed for any of their favorite users for the last x hours of activity.

The problem I'm running into is that if a user uploads five photos over the course of a half hour or something, I just want that to be one line in the feed, not an entry for each photo upload.

Same goes for profile updates.

I need to query the data so the user will see something like this:

user x updated their mood! (I'm tired) on Apr 4, 2009 10:35 pm
user y uploaded x new photos on April 4, 2009 10:20 pm
user x updated their profile on April 4, 2009 10:15 pm

How do I group the photo updates into one record returned in a query based on all records being within let's say an hour of each other?

Is there a way to do this with one query?

Thanks!

Upvotes: 0

Views: 1067

Answers (2)

Frank Crook
Frank Crook

Reputation: 1466

You want something like

SELECT * FROM update_log WHERE update_time > NOW() - 30 MINUTES;

With 30 minutes being the period of time you're looking back.

I'm assuming you just needed to know how to return in a single query the updates of the last 30 minutes.

If you're trying to group all of the photos together into 30 minute blocks, say for the last two days, you'd be better off changing your database structure and creating a photo_group table [containing a primary key, userid, and time of creation] and adding a group_id column to the update_log table.

When adding a new photo, check for an existing group created by that user in the last 30 minutes.

SELECT * FROM photo_group WHERE user_id = XXX AND created > NOW () - 30 MINUTES;

If one does not exist, create it. Link the photos to the newest by adding the primary key of the photo_group table as the group_id in the update_log.

When you retrieve rows later, you can group them by group_id using your scripting language.

The disadvantage of this method is your grouping structure will be difficult to modify later, as previous entries will be grouped by their old groups when you change the rules for creating new groups.

If you want to do this without storing the groups, you'll have to handle the logic in your scripting language by grouping the photos together in a loop that checks the creation time of a photo, groups following photos in an array with it if they have been created within a specific time period, or restarts the loop, using the most recent photo that did not fit with the previous. This would be more overhead than adding a new table, but it would be easier to modify later.

Upvotes: 2

drarc
drarc

Reputation: 248

Have you considered trying to do this with PHP rather than SQL queries? It might be less complex to query the results you need (All updates between these times) and then use PHP to compare the timestamps in order to determine how they should be grouped.

Upvotes: 0

Related Questions