Количество непрочитанных сообщений в приложении PHP

#php #javascript #sql #message

#php #javascript #sql #Сообщение

Вопрос:

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

Хотя это может быть простой проблемой для решения, я не знаю, каким был бы наилучший метод с точки зрения производительности :

  1. Выполняет простой SQL COUNT () непрочитанных сообщений при каждой загрузке страницы (мгновенно уведомляет об изменениях, но это может сильно повлиять на производительность?)
  2. Сделайте то же самое, но кешируйте результат в течение X минут (мы создаем раздражающую задержку)
  3. То же, что и 2., но обновляется только тогда, когда мы читаем сообщение или когда сообщение отправляется нам (может занимать много оперативной памяти / перегружать диск, поскольку мы создаем одну постоянную запись / файл на пользователя: мы не можем сохранить его в $ _SESSION, потому что нам нужно обновлять его, когда другой пользователь отправляет нам сообщение)

Все мои решения в некоторой степени основаны на сервере, потому что я не очень знаком с JS. Но если существует лучшее решение с использованием JavaScript, все в порядке.

Спасибо за вашу помощь!

Ответ №1:

Я бы предложил 4-е:

Как только пользователю было отправлено новое сообщение, вы обновляете счетчик в memcache . Вы создаете простое ajax-приложение на стороне клиента, отправляющее запрос каждые X секунд. На стороне сервера вы просто проверяете, есть ли непрочитанные сообщения. При обновлении страницы вам не нужно запрашивать базу данных, так как вы memcache очень быстро получаете количество.

Это то, что я бы сделал, если бы у меня было узкое место в DB (в 90% случаев DB — самая загруженная часть любого приложения, управляемого базой данных).

Это то, что мы обычно делаем на высоконагруженных веб-сайтах: мы пытаемся избежать любых ВСТРЕЧНЫХ запросов. Если нет, мы денормализуем базу данных для хранения счетчиков прямо в соответствующей таблице в качестве еще одного столбца, например, если вы не можете использовать memcache , вы бы сохранили счетчик непрочитанных сообщений в качестве столбца для Users таблицы.

Комментарии:

1. Да, это, кажется, лучшее решение. Однако это означает добавление еще одной зависимости к моему приложению. Спасибо за ответ!

2. Да. Это довольно сложно поддерживать, особенно когда ваше приложение растет, но cmon! facebook использует MySQL в качестве хранилища значений ключей и в основном полагается на memcache . Имея дело с высокими нагрузками, вам придется чем-то пожертвовать.

3. @Artefact amp; @Nemoden когда-либо слышали о: «Преждевременная оптимизация — корень всего зла». Устанавливать memcache и другие материалы до запуска приложения неразумно. Сначала вы должны просто создать свое приложение простым способом и обновлять его, когда возникают проблемы с производительностью.

4. @RJD22 Я знаю об этом выражении. Я прочитал кое-какую литературу. Я также работаю над приложением с более чем 600 тысячами пользователей каждый день и более чем 2000 обращениями в секунду. SELECT COUNT(*) WHERE обращение к главному серверу может вызвать проблемы с производительностью. Кто-нибудь говорил, что мы имеем дело с приложением, которое не запущено? Я думаю, что если @Artefact2 спросил об этом, он обеспокоен производительностью. Зачем ему иначе, если с SELECT COUNT() все работает нормально?

5. @Nemoden Он все еще разрабатывает его. Имо, лучше сначала запустить что-то простое, прежде чем приступать к оптимизации. Возможно даже, что в его случае количество — наименьшая из его забот: P

Ответ №2:

Я бы выбрал третий вариант, за исключением того, что я бы добавил memcached в качестве решения 4.

Ответ №3:

Есть ли простой SQL COUNT () непрочитанных сообщений при каждой загрузке страницы (мгновенное уведомление об изменениях, но это может сильно повлиять на производительность?)

Пока у вас есть приличная структура таблицы, COUNT() — довольно быстрая команда. Я бы не стал кэшировать эту конкретную команду. Вместо этого я бы проработал другие запросы, чтобы убедиться, что вы возвращаете только те данные, которые вам нужны, когда показываете им список. Например, если все, что вам нужно, это выдержка, я бы обязательно сделал что-то вроде этого:

 SELECT id, author, msgdate, substring(body, 0, 50) from table where recipient = ?
  

вместо

 SELECT * from table where recipient = ?;
  

Комментарии:

1. Я все же немного беспокоюсь о производительности COUNT (), потому что у одного сообщения может быть несколько получателей, каждый из них мог прочитать сообщение, а мог и не прочитать, и т.д. Подсчет непрочитанных сообщений фактически включает в себя АНТИСОЕДИНЕНИЕ…

Ответ №4:

Имхо. Лучше всего позволить клиенту пинговать сервер и отправлять json обратно с количеством непрочитанных сообщений. Подсчет в mysql должен быть быстрым, поэтому я не вижу причин не использовать его. Просто отфильтруйте результаты в сеансе чата.

Для части базы данных. Лучшим способом было бы сохранить заполненное new_message в таблице вашей базы данных и присвоить ему значение по умолчанию 1, а это значение установить равным 0, когда сообщение будет загружено.