Чат и не прочитанные сообщения пользователя, как правильно спроектировать БД?

Нужно сделать чат что то на подобии как сообщения vkontakte. Т.е любой может создать беседу пригласив в комнату n-е количеств людей, после чего между ними идет общение, в любой момент можно закрыть окно чата но открыв его через определенное время все равно увидеть все сообщение от участников беседы и вот для такого пользователя и нужно сделать вывод сообщение, что у него есть непрочитанные сообщения в конкретном чате(комнате)

Я набросал схему БД, но вот как правильно реализовать возможность получить не прочитанные сообщения для каждого пользователя в комнате не могу сообразить. Была идея связать пользователя и сообщение через вспомогательную таблицу read_user_mess с флагом было ли прочитано сообщение пользователем но напрягает, что при создании сообщение придется делать кучу вставок в read_user_mess для user которые находятся к комнате в которую пришло сообщение такой вариант конечно приемлем если туда будут попадать записи только тех кто прочитал сообщение, а не сразу всех кто находится в комнате но тогда как создать запрос на выборку сообщений не прочитанных пользователем к комнате
chat.jpg
  • Вопрос задан
  • 5650 просмотров
Пригласить эксперта
Ответы на вопрос 3
Fesor
@Fesor
Full-stack developer (Symfony, Angular)
Вставки не проблема, так как вы всеравно должны будете организовать какой-то буфер в памяти, например для reddis и обновлять все это добро пачками а не по одному, и желательно в отдельном потоке, через ZeroMQ например.

Собственно по этой причине особо напрягаться по поводу архитектуры базы не стоит, в любом случае стоит избегать общения с базой из чатика, так как это в любом случае будет безумно медленно.
Ответ написан
web-craft
@web-craft
Директор, Web-Craft Studio
Если все верно понял, то
У сообщения подразумевается дата.
У пользователя можно писать дату выхода из чата.
соответственно непрочитанные - просто разница по дате.
Ответ написан
undassa
@undassa
Last.Backend
Для хранения недоставленный сообщений целесообразнее использовать redis и сделать это следующим образом:

Если пользователь в данный момент не онлайн, записывать сообщения в редис через rabbtimq (ZeroMQ) специальными воркерами. Тогда удастся размазать нагрузку и не будет пиков.

Так же желательно все сообщения для конкретного пользователя хранить в его "личном" списке, а не списке комнаты, тогда есть возможность (при необходимости) при успешном получении - очищать кеш и redis не будет раздуваться.

Если же необходимо хранить историю сообщений - желательно написать воркер, который раз в n секунд будет забирать данные из кеша и записывать в БД в отдельную коллекцию или таблицу, и так же очищать кеш.

При подключении пользователя просто делать запрос на получение недоставленных сообщений из кеша, если кеш пуст - загрузить из БД из специальной таблицы недоставленных.

Зачем нужна отдельная таблица (коллекция) - так как непрочитанные сообщения - данные, находящиеся постоянно в работе - данная таблица не будет постоянно увеличиваться в размерах (будет, но существенно медленнее, ведь её так же надо очищать), соответственно выборка по данной таблице с учетом индексации будет гораздо быстрее.

Успехов :)
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы