#php #javascript #sql #message
#php #javascript #sql #Сообщение
Вопрос:
В настоящее время я разрабатываю простое PHP-приложение, в котором пользователи могут отправлять сообщения друг другу. Сообщения хранятся в базе данных SQL. Я хотел бы указать количество непрочитанных сообщений в меню на каждой странице, чтобы пользователь мог быстро видеть, есть ли у него новые сообщения, не проверяя периодически входящие.
Хотя это может быть простой проблемой для решения, я не знаю, каким был бы наилучший метод с точки зрения производительности :
- Выполняет простой SQL COUNT () непрочитанных сообщений при каждой загрузке страницы (мгновенно уведомляет об изменениях, но это может сильно повлиять на производительность?)
- Сделайте то же самое, но кешируйте результат в течение X минут (мы создаем раздражающую задержку)
- То же, что и 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, когда сообщение будет загружено.