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,
Since a given pair of users can have at most one conversation, there is no need to "invent" separate key just to identify conversations. Also, the wording of your question seems to suggest that a message is always sent to a single user, so I'd probably go with something like this:
Now, there are several things to note about this model:
I1
is relatively expensive. There are ways to work around that, but the resulting complications are probably not worth it.With this data model, it becomes rather easy to sort the "conversations" (identified by user pairs) by the latest message. For example (replace 1
with desired user's USER_ID):
SELECT *
FROM (
SELECT USER1_ID, USER2_ID, MAX(SEND_TIME) NEWEST
FROM MESSAGE
WHERE (USER1_ID = 1 OR USER2_ID = 1)
GROUP BY USER1_ID, USER2_ID
) Q
ORDER BY NEWEST DESC;
(OR USER2_ID = 1
is the reason for the secondary index I1
.)
If you want not just latest times, but also latest messages, you can do something like this:
SELECT * FROM MESSAGE T1
WHERE
(USER1_ID = 1 OR USER2_ID = 1)
AND SEND_TIME = (
SELECT MAX(SEND_TIME)
FROM MESSAGE T2
WHERE
T1.USER1_ID = T2.USER1_ID
AND T1.USER2_ID = T2.USER2_ID
)
ORDER BY SEND_TIME DESC;
You can play with it in the SQL Fiddle.
1 If that's not the case, you can use monotonically-incrementing INT instead, but you'll have to SELECT MAX(...)
yourself since auto-increment doesn't work on PK subset; or simply make it PK alone and have secondary indexes on both USER1_ID and USER2_ID (fortunately, they would be slimmer since the PK is slimmer).