- PVSM.RU - https://www.pvsm.ru -
Часто возникает задача подсчета количества посещений той или иной страницы портала или подсчета кликов по какой-то ссылке. Например. может быть интересно подсчитать количество просмотров статьи или объявления, число кликов по «показать номер телефона» на странице объявления о продаже и т.д. и т.п.
Главное точно понимать, для чего вы планируете использовать эти счетчики и для чего они могут понадобиться в обозримом будущем. Нужно ли по ним выбирать/сортировать/группировать сущности или вам просто нужны редкие разовые отчеты (например раз в сутки)? А может, вы хотите показывать эти счетчики в админке или в личном кабинете пользователя? Хотите ли вы в реальном времени показывать эти числа или можно ограничиться часовой/суточной отсечкой? В зависимости от этих и, возможно, еще каких-то критериев будет зависеть выбор способа подсчета и хранения счетчиков.
Подсчет кликов/визитов
Задачу подсчета кликов/визитов можно решать разными способами:
На данном этапе необходимо решить, нужно ли нам считать визиты поисковых роботов. Возможно, вы не захотите считать запросы, совершаемые из внутренней сети. Также может быть интересным считать только запросы авторизованных пользователей и т.д.
Также важно понять, насколько критична точность подсчета, можно ли ошибиться на 1-2-3 единицы или нет. От этого может зависеть многое. Если важна точность, то можно пренебречь производительностью, или же наоборот, если важна производительность (например, скорость отдачи страницы), то можно незначительно пренебречь точностью.
Хранение счетчиков
Хранить счетчики можно тоже по-разному:
Пример из жизни
Давайте рассмотрим конкретный пример из нашей практики. Сразу скажу, что мы используем MySQL.
Задача: подсчет числа визитов страницы объявления, без учета Web-ботов. Также нужно считать общее количество просмотров всех объявлений у автосалона.
Важные моменты:
Сначала попробовали реализовать «в лоб». Мы создали в таблице сущности поле views_count (аналогично в таблице автосалона) и обновляли его при каждом просмотре страницы объявления (делали UPDATE <table> SET views_count = views_count +1 WHERE id = <id>
). При тестировании сразу обнаружилась очевидная проблема — очередь из запросов на обновление и, как следствие, увеличение времени на получение данных из этой таблицы при отображении листингов объявлений.
Подумали-подумали, и решили, что количества просмотров объявлений (views_count) в листингах нам не нужны, а нужны они нам только в админке и в личном кабинете пользователя. А значит и не зачем это поле хранить в таблице сущности, блокируя тем самым эту таблицу обновлениями. Вынесли это поле в отдельную таблицу, состоящую из 2 полей: id сущности (объявления) и, собственно, views_count (для автосалонов такое не делали, т.к. там нагрузка на таблицу гораздо меньше). Теперь при необходимости сортировки по числу просмотров (в админке) и для получения числа просмотров в личном кабинете пользователя делаем INNER JOIN этих двух таблиц.
Отлично, одна проблема решена, теперь поиск объявлений, да и просто листинги, стали работать быстро. Но теперь появилась очередь из апдейтов этой новой таблицы. Стали думать, как можно сократить число апдейтов и их интенсивность, но при этом не сильно потерять точность и актуальность данных о количестве просмотров.
Пришли к такой схеме:
В итоге таблицу счетчиков обновляем не 100 раз (размер окна), а в среднем 7 раз.
К тому же для реализации всей этой схемы мы написали базовый класс размером всего 70 строк и каждый последующий наследник (для каждого счетчика) состоял в среднем из 50 строк с реализацией всего двух виртуальных методов.
Какие альтернативы мы рассматривали
Всем удачи с подсчетами. Не изобретайте свои велосипеды без реальной необходимости.
Автор: graywolfxxx
Источник [2]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/mail-ru/51012
Ссылки в тексте:
[1] http://top.mail.ru/: http://top.mail.ru/
[2] Источник: http://habrahabr.ru/post/206494/
Нажмите здесь для печати.