I have a private messaging system that uses a mysql database.
Messages are passed between two users.
However, when any user deletes the conversation history, it should not be deleted in the other user.
I could create an Additional column called "deleted_users" and use LIKE when listing messages.
But I'm worried about performance and I need your help.
id
user_from
user_to
msg
1
82
85
test
2
85
82
test
Related
Okay, let me explain.
You know how Facebook Messenger and Discord both have the last messaged friends list? It is a list of all of your friends order by whoever texted you last. Now, if you had over 100 people in that list, it would be better to send the list to the client in chunks of 10. Once the client reaches the bottom, it asks for the next 10. This can be done with the LIMIT offset, amount.
But now, the problem. The user might open the messenger, talk to someone for 10 minutes, and then scroll further down in the last messaged friends list. In this case, the table has changed before the user has retrieved the full list. The list in database is now in a different order because someone messaged them in the meanwhile and is now on top of the list, but the client already has the first chunk of the list, but this doesn't contain the people that texted them.
In case my explanation was not enough, here's a visual demonstration:
Visual demo
'Last messaged friends' list in database (ordered by latest timestamp):
Person 23
Person 77
Person 93
Person 99
Person 67
Person 85
User connects, asks for the first 3 entries.
Client now has (ordered by latest timestamp):
Person 23
Person 77
Person 93
'Person 99' messages that user. 'Person 99' is now on top of the list.
'Last messaged friends' list in database (ordered by latest timestamp):
Person 99
Person 23
Person 77
Person 93
Person 67
Person 85
User scrolls down. Client asks for the next 3 entries.
Client now has (ordered by latest timestamp):
Person 23
Person 77
Person 93
Person 93 (duplicate)
Person 67
Person 85
('Person 99' missing)
Is this something I could fix/implement with a more advanced SQL query?
If I can't, how could I implement this in other ways?
For information, I have a Socket.io (a.k.a more advanced WebSocket) connection between the server and the client, I can send whatever necessary information thru that.
It sounds like you want aggregation to avoid duplicates:
select person_id
from messages
group by person_id
order by max(timestamp) desc;
Thank you, Hector Vido, for the suggestion. (he made a comment right below my question, go upvote)
"Selecting messages by timestamp don't solve this? You keep the last timestamp and then ask by anoter 10 registries >= that timestamp"
Solution
I'll keep the oldest and newest timestamp in the client side.
If the client scrolls down, I will request 10 entries before the oldestTimestamp and then the new oldestTimestamp will be the oldest timestamp of the received entries.
Also after every 10 seconds, I could request for entries after the newestTimestamp and then the new newestTimestamp will be the newest timestamp of the received entries.
I'm building a pretty simple chat app that allows both 1 on 1 message and chat rooms for groups of people. I'm planning to have one Message table to store all chat messages, each message will also keep the sender ID and receiver ID, in the case of messages sent in a chat room, we also keep the ID of that chat room. Below is the table:
Message Table
ID Message Sender Receiver Chatroom Timestamp
1 Hello, David 123 321 1495330074
2 Hi, Linda 321 123 1495930032
3 Hi everyone! 456 999 1495930132
4 What up? 321 123 1495930192
...
Then if I'm user 321, and I want to retrieve my conversation with user 123, I just need to SELECT * FROM Message WHERE Sender=123 or Receiver=123 or Sender=321 or Receiver=321 and Chatroom IS NULL
There is one issue with this design - a user can't delete a message that he doesn't want to see any more.
To solve that, I think I can have a separate table to store what messages a user received or sent, like below:
User Message Table
ID UserID MessageID
1 123 1
2 321 1
3 321 4
...
It seems a little redundant, but this way David can delete a message in his conversation with Linda, while Linda can still see full conversation history.
Is there better design of the tables? And is this good practice to throw all chat messages in one giant table? Should I add some index to make query faster?
You can use this query.
delete from Message
where sender = 123 and user = 321
But this will delete all the chat messages between this user and sender. To delete specific message you can use ID
delete from Message
where ID = 1
I'm working on a email project. I would like to display email in threads just like gmail.
What is the best approach to display mails in thread?
I have checked jwz threading algorithm. But looks like that algorithm is written for projects that has no databases.That algorithm focuses on these three header keys. Message-ID, In-Reply-To and References
Can someone tell me what is the proper, efficient and most accurate way to achieve threading using mysql database.?
Do I have to use separate table for threads and references?
If possible give me some sample mysql queries. So I can understand better.
Thank you.
Any message board design eg wordpress etc should also works for email. I also come up with a design:
email.id user_id subject status folder created updated ...other info you'd save
1 123 Hello New Inbox Y-m-d.. Y-m-d.. ...
2 3456 World Replied Inbox ...
reply.id email_id reply_to_id user_id created email_txt ip ...
10 1 0 890 Y-m-d.. Hi ...
20 2 0 5678 ...
30 2 20 3456 ... Replyto 2
55 2 30 5678 .... Replyto 3
So in your email.folder.index page:
SELECT * FROM email WHERE user_id = 12345 ORDER BY updated desc LIMIT 50
And when you click one an email on index page, goto email details page:
SELECT * FROM reply WHERE email_id = 2 ORDER BY created, reply_to_id
The key magic is that the tree is built based on reply_to_id
The following is a simplified table structure showing messages belonging to a single mail trail. i.e. the trail started with messageID 46 (where parentMessageID = 0). Message 47 is a reply to message 46. Message 89 is a reply to message 47.
tblMessages
messageID parentMessageID
-----------------------------
46 0
47 46
89 47
The table would obviously have thousands of message records.
How would you query the table to get all messages in a particular trail, e.g. the trail shown above?
Wouldn't it be better to store a conversation identifier?
The problem you're going to have is that you have no indication of the depth level, and so trying to loop over is almost impossible. It would be more logical to set the parentMessageID to the very root (i.e. where its parentMessageID == 0), and then order them by date.
The problem scenario is:
I have a database table 'User_Datails_Table' with fileds(id,username, luckyNumber).
All logged in users can updated their 'luckyNumber' as they wish. Also a user has option to view all the existing user details. There is an option to sort(DESC) the user details based on 'luckyNumbers'.
The requirement is such that I need to query the database with LIMIT values. For example,query fetching 1st two records(LIMIT 0,2), then next query fetching next 2 records(LIMIT 2,2) so on.
Consider the database contains 4 record:
id username luckyNumber
1 USER1 67
2 USER2 66
3 USER3 64
4 USER4 63
Two user(USER1 and USER3) are logged in.
If USER3 fetches the first two records using LIMIT 0,2( result is USER1 and USER2) and USER1 changes his luckyNumber to 62(simultaneously).
Now if USER3 fetches the next two records using LIMIT 2,2( result is USER4 and USER1). So USER1 gets repeated in the result.
I use php to fetch the mysql database. How can such a scenario be handled? Does mysql handle this automatically?