grigor007
@grigor007
http://goldapp.ru

Как правильно реализовать уведомления о новых сообщениях, чтобы mysql б. д. не упала?

Привет!

У меня пока 2 идеи как это сделать, первая ( чувствую, что плохая ):

1) Просто делать Select count(*) from messages where user_id = 1 AND status = NULL

То есть каждый раз пробегать всю таблицу и считать сколько новых сообщений - думаю на 500 человек онлайн б. д. откажет.

2) Сделать отдельную таблицу, где одна запись - это один user_id. И в этой записи будет поле mess_ids - где через запятую будут перечислены id непрочитанных сообщений. Таблица будет обновляться при отправке другим пользователем сообщения текущему пользователю. Всяко быстрее чем select count(*)

Может подскажите другие решения на php и mysql. Как организовать логику таблиц и логику работы? Без сторонних решений вроде reactPHP и т. п.?
  • Вопрос задан
  • 5801 просмотр
Решения вопроса 1
deMone
@deMone
Техдиректор — tech-director.ru
Оба решения так себе.

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

В таблице сообщений сделайте поле is_read (true/false), на которое повесьте индекс, так вы сможете определить, какие сообщения в данный момент не прочитаны.

Держать список ID через запятую в одном поле неэффективно и бессмысленно.
Ответ написан
Пригласить эксперта
Ответы на вопрос 5
DmitriyEntelis
@DmitriyEntelis
Думаю за деньги
Тут почему то все скатились на обсуждения счетчиков.
Счетчик действительно хорошо делать в redis, особенно если этот счетчик часто меняется.
Хотя если это счетчик просто не прочитанных сообщений у пользователя - вполне можно его хранить и как написано у автора по 2му варианту.

Но заголовок вопроса автора как я понимаю в другом - "как реализовать уведомление".
Видимо подразумевается что кучи веб страничек будут слать пачки ajax запросов.

При такой схеме узким местом будет не sql, а очень даже php.
Правильное решение - поднять любой comet сервер.
Можно на php (медленно и криво), можно на node.js + socket.io (быстро и хорошо)
Ответ написан
Rpsl
@Rpsl
Кратко о себе
второе решение весьма стандартно, только лучше не в отдельную таблицу это класть, а в любое key=>value хранилище, например memcaced или redis, где ключ это id пользователя.

При изменение данных просто сбрасываете ключ.
Ответ написан
Select count(*) from messages where user_id = 1 AND status = NULL


Вполне норм решение. Просто нужен индекс по user_id + status. Когда начнет отказывать база тогда и подумаете об оптимизации (memcached, вот это все). Преждевременная оптимизация - корень большинства бед.
Ответ написан
Комментировать
Сделать "счетчик" (хоть в таблице пользователя, хоть в k-v хранилище), который инкрементить при поступлении нового сообщения и декрементить при прочтении оного.

И в этой записи будет поле mess_ids - где через запятую будут перечислены id непрочитанных сообщений.

не надо так
Ответ написан
Комментировать
FacedSID
@FacedSID
Согласен с комментарием выше. nodeJS + socket.io + возможно redis (если нужно что-то посложнее).
Очень полезно, если пользователь пользуется несколькими клиентами. Я как то пытался изобрести велосипед на mysql + ajax запросы, но возникала куча сложностей с получением актуальных обновлений. Дак вот nodeJS + socket.io меня спасли! Времени на разработку потратил раза в два меньше, чем на изобретение велосипеда с mysql.
Ответ написан
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы