I have created a messaging system for users, it allows them to send a message to another user. If it is the first time they have spoken then a new conversation is initiated,
I think you do not need to create a userconversation table.
If only user can have only one conversation with someone, the unique id for this thread is a concat between userId and friendId. So I move the friendId column in usersmessage table. The problem of order (friendId-userId is the same thread of userId-friendId) can be solved so:
SELECT CONCAT(GREATEST(userId,FriendId),"_",LEAST(userId,FriendId)) AS threadId
Now there is a problem of fetch the last message after a GROUP BY threadId.
I think is a good solution make a concat between DATE and message and after a MAX on this field.
I assume, for simplicity, column date is a DATETIME field ('YYYY-mm-dd H:i:s') but it not need because there is FROM_UNIXTIME function.
So the final query is
SELECT
CONCAT(GREATEST(userId,FriendId),"_",LEAST(userId,FriendId)) AS threadId,
friendId, MAX(date) AS last_date,
MAX(CONCAT(date,"|",message)) AS last_date_and_message
FROM usermessages
WHERE userId = :userId OR friendId = :userId
GROUP BY threadId ORDER BY last_date DESC
the result of field last_date_and_message is something like so:
2012-05-18 00:18:54|Hi my friend this is my last message
it can be simply parsed from your server side code.