В настоящее время я работаю в частном чате между двумя пользователями, использующими NodeJS, AngularJS, MySQL и Socket.IO. Я хочу как-то сохранить чаты, чтобы вы не только увидели новый чат, который вы пишете, который передается через Socket.IO, но и сообщения, которые вы написали перед вашими текущими сеансами.
Как правильно сохранить эти предыдущие чаты на моем сервере?
Обычный способ сделать это:
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)
Однако эта структура имеет проблему: нет простого способа эффективно сортировать последние N сообщений с помощью "id DESC", потому что у вас будет что-то в вашем 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
Таким образом, когда пользователь открывает окно чата другим пользователем, вы легко можете найти chat_id (или chatroom_id) с индексированием и быстро перечислить последние сообщения, также используя индексный поиск и без каких-либо ролей.
Старые сообщения должны быть обрезаны и перемещены в таблицу архивов, чтобы таблица сообщений была маленькой и кэшируемой в ОЗУ.