如何在两个用户之间正确存储聊天

时间:2017-07-30 13:46:20

标签: mysql angularjs node.js sockets chat

我目前正在使用NodeJS,AngularJS,MySQL和Socket.IO进行私人聊天。我想以某种方式保存聊天记录,这样你不仅可以看到你正在编写的新聊天通过Socket.IO传输,还可以看到你在当前会话之前写的消息。

如何在服务器上正确存储这些先前的聊天记录?

1 个答案:

答案 0 :(得分:1)

通常的做法是:

Table messages:
message_id    PRIMARY KEY
sender_id     FOREIGN KEY
recipient_id  FOREIGN KEY
Index on (sender_id, recipient_id, message_id)
Index on (recipient_id, sender_id, message_id)

然而,这个结构有一个问题:没有简单的方法可以通过“id DESC”有效地对最后N个消息进行排序,因为你的WHERE中会有一些东西,比如“WHERE sender_id = ... OR recipient_id = .. “这将使最后两个索引(用于快速排序)有点无用。

因此,更智能的结构是:

Table chatrooms:
chatroom_id PRIMARY KEY

Table chatrooms_users
chatroom_id FOREIGN KEY
user_id FOREIGN KEY

现在,当两个用户(或更多)想要开始聊天时,您可以从所述表创建或重用聊天室,并将相关行插入chatroom_users以将聊天室链接到其活动成员。这应该在用户加入/离开聊天室时更新。

如果对话只涉及两个用户(并且从不超过两个),那么您可以使用更简单的结构:

Table conversations
conversation_id PK
first_user_id   FOREIGN KEY
second_user_id  FOREIGN KEY

反正。整个想法是为我们的两个用户或聊天室之间的对话线程提供唯一的标识符。然后,消息表变得更加简单:

Table messages:
message_id PK
chatroom_id (or conversation_id) FK
sender_id FK
Index on (chatroom_id, message_id)

在这种情况下,请注意最后一个索引优化了这个:

SELECT * FROM messages WHERE chatroom_id=constant ORDER BY id DESC LIMIT 10

因此,当用户与另一个用户打开聊天窗口时,您可以使用索引查找轻松找到conversation_id(或chatroom_id),并使用索引查找快速列出最后的消息,而不进行任何排序。

旧邮件应该被修剪并移动到存档表中,以使邮件表保持较小并且可以缓存在RAM中。