2009-11-26 2 views
0

У меня есть сайт, на котором пользователи могут просматривать большое количество сообщений. Каждый раз, когда это делается, я запускаю запрос, похожий на UPDATE table SET views=views+1 WHERE id = ?. Тем не менее, существует ряд недостатков этого подхода:Отслеживание просмотров данной строки

  • Невозможно отслеживать, когда возникают просмотры страниц - они просто увеличиваются.
  • Обновление таблицы, которая часто будет, насколько я понимаю, очистить кэш MySQL строки, тем самым делая следующий SELECT этой строки медленнее.

Поэтому я считаю, используя подход, при котором я создаю таблицу, скажем:
object_views { object_id, year, month, day, views }, так что каждый объект имеет один ряд пр. день в этой таблице. Затем я периодически обновлял столбец views в таблице objects, чтобы мне не пришлось делать дорогостоящие соединения все время.

Это самое простое решение, о котором я могу думать, и, похоже, оно также имеет наименьшее влияние на производительность. Вы согласны?

(Сайт построен на PHP 5.2, Symfony 1.4 и Doctrine 1.2 в случае, если вам интересно)

Edit:
Целью является не веб-аналитика - Я знаю, как сделать это, и это уже на месте. Есть две цели:

  • Позвольте пользователю узнать, сколько раз данный объект показывался, например, сегодня или вчера.
  • Разрешите модераторам сайта видеть простых просматривать статистику, не входя в Google Analytics, Omniture или любое другое решение. Кроме того, результаты в бэкэнд должны быть в реальном времени, функция, которую GA не может предложить в это время. Я не хочу использовать API Analytics для извлечения данных об использовании (не в реальном времени, для GA требуется javascript).

ответ

1

Цитата: Обновление таблицы, которая часто, насколько я понимаю, часто очищает кеш MySQL строки, тем самым делая следующий SELECT этой строки медленнее.
Существует намного больше, чем это. Это убийца базы данных. Я предлагаю вам сделать таблицу следующим образом: object_views {object_id, timestamp} Таким образом вы можете агрегировать функцию object_id (count()). Итак, каждый раз, когда кто-то просматривает страницу, вы записываете запись INSERT в таблицу. Время от времени вы должны очистить старые записи в таблице. Утверждение UPDATE EVIL :) На большинстве платформ он будет в основном пометить строку как удаленную и вставить новую, что сделает таблицу фрагментированной. Не говоря уже о проблемах с блокировкой.

Надежда, что помогает

0

Прежде всего, просто краткое замечание, почему бы не суммировать год, месяц, день в DATETIME, это имело бы больше смысла в моем сознании.

Также я не совсем уверен, что именно вы делаете, если это для целей маркетинга/веб-статистики, вам лучше использовать инструмент, созданный для этой цели.

В настоящее время существует две большие семьи инструмента, способного дать вам представление о статистике доступа к сайту, бревенчатый один на основе (awstats, вероятно, является наиболее популярным), AJAX/1pixel изображений на основе один (google analytics будет самым популярным) ,

Если вы предпочитаете создавать собственную базу данных статистики, вам, вероятно, удастся создать парсер журнала с помощью PHP. Если вы обнаружите, что обработка журналов apache (или журналов IIS) слишком велика, вы, вероятно, заставите свое приложение выработать некоторые настраиваемые журналы, созданные более простым способом.

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

+0

я уже использую Google Analytics и ClickTale, поэтому я хорошо освещены на веб-аналитики части. Я вижу вашу точку зрения в поле 'DATE', но вычисления, касающиеся« количества просмотров, которые у меня были в ноябре », были бы, насколько я знаю, более быстрыми, если бы вместо них было просто 3 целочисленных поля. Анализ журналов, безусловно, не является вариантом, для которого я бы пошел. – phidah

+0

Для ведения журнала я обычно использую отдельные колонки год, месяц, день, час, потому что это упрощает генерацию статистики. 'GROUP BY hour, day, month, year' для почасовой статистики,' GROUP BY month, year' за месячную статистику и т. Д. – Rob

+0

Я обновил вопрос, чтобы лучше отразить то, что я ищу. – phidah

0

Наряду с такими же чертами, как Rage, вы просто не будете получать те же результаты, что и сами, когда есть миллионы сторонних инструментов регистрации.Если вы ежедневно отслеживаете, то базовая программа, такая как webtrends, отлично умеет отслеживать хиты, особенно если ваш URL содержит идентификаторы предметов, которые вы хотите отслеживать ... Я не могу это подчеркнуть, это все о URL-адресе, когда речь заходит об этих инструментах (например, Wordpress допускает множество различных конструкций URL-адресов)

Теперь, если вы ищете отслеживание «показов», то это еще одна игра в мяч, потому что вы, вероятно, отслеживаете каждый объект, страницу , пользователя и, возможно, взвешенное значение, основанное на местоположении на странице. Если это так, вы можете сохранить свою производительность, разместив отслеживание на другом сервере, где вы можете запускать и забывать. Раньше я работал с использованием SQL-обновления с идентификатором и строковой версией даты ... таким образом, когда дата изменилась с 20091125 по 20091126, это простой запрос без накладных расходов, скажем, датированной функции.

+0

Я обновил вопрос, чтобы лучше отразить то, что я ищу. – phidah

0

Если вы собираетесь это сделать, почему бы не просто зарегистрировать каждый доступ? MySQL может кэшировать вставки в непрерывных таблицах достаточно хорошо, поэтому не должно быть заметного замедления из-за вставки. Вы всегда можете запустить Show Profiles, чтобы узнать, какова эффективность на самом деле.

В выпуске datetime вы всегда можете использовать GROUP BY MONTH(accessed_at) , YEAR(accessed_at) или WHERE MONTH(accessed_at) = 11 AND YEAR(accessed_at) = 2009.

+0

Это привело бы к огромному количеству строк, и я предпочел бы немного заполнить данные перед их сохранением. – phidah

Смежные вопросы