За последние 24 часа нас посетили 17864 программиста и 1611 роботов. Сейчас ищут 1416 программистов ...

Модуль статистики

Тема в разделе "Решения, алгоритмы", создана пользователем GvOzD, 8 апр 2008.

  1. GvOzD

    GvOzD Активный пользователь

    С нами с:
    16 фев 2007
    Сообщения:
    103
    Симпатии:
    0
    Хотел написать модуль сбора статистики на сайте , что бы не загружать клиентскую часть написал один скриптик всего лишь с одним запросом , он пишет в базу ip,дату,http_via,http_user_agent,http_referer,user_id (для авторизованных).Этот скрипт приинклудил ко всем остальным скриптам. В администраторской части нужны следующие отчеты
    1. Посещаемость сайта
    2. Популярные страницы
    3. Новые пользователи
    4. Ссылающиеся страницы
    5. Браузеры и ОС
    Все отчёты я без труда формирую ,кроме первого.Для отчёта посещаемости хотел выводить таблицу с шапкой
    • Дата
    • Всего (Просмотров, Хостов)
    • Роботы (Просмотров, Хостов)
    • Посетители (Просмотров, Хостов, Пользователей)
    Ну как в CNStats и вошёл в полный ступор. Что бы сформировать такую табличку, приходиться в цикле описывать ещё по три запроса или джойнить одну и ту же таблицу, чисто по разному сгруппированную.Может кто-нибудь посоветует как лучше написать , добавить в клиентскую чаcть ещё несколько запросов или каким-то образом оптимизировать административную???? или использовать вообще другой подход???
     
  2. Anonymous

    Anonymous Guest

    пример
     
  3. GvOzD

    GvOzD Активный пользователь

    С нами с:
    16 фев 2007
    Сообщения:
    103
    Симпатии:
    0
    Горбунов Олег
    Таблица с полями | id | ip | date | http_via | agent| language | url | referer| user_id | group_id | , каждый раз когда пользователь обновляет страницу в неё пишется информация.

    Для формирования отчёта за 30 последних дней делал так

    PHP:
    1. <?
    2. include_once("../config.php");
    3.  
    4. $sourse=mysql_query("SELECT DATE_FORMAT(date,'%Y-%m-%d') AS date,count(*) AS count FROM stats GROUP BY DATE_FORMAT(date,'%Y-%m-%d') LIMIT 30");
    5. while($result=mysql_fetch_assoc($sourse))
    6. {
    7.     $result['hostov']=mysql_num_rows(mysql_query("SELECT * FROM stats WHERE DATE_FORMAT(date,'%Y-%m-%d')='".$result['date']."' GROUP BY ip"));
    8.     echo $result['date'].'&nbsp;|&nbsp;'.$result['count'].':просмотров&nbsp;|&nbsp;'.$result['hostov'].':хостов<br>';
    9. }
    10. ?>
    Это только посещаемость всех и пользователей и ботов , а ещё хотелось бы выводить по каждым отдельно.
    Сильно не ругайте , но в голову ничего умнее не приходит.Можно всё это оформить в одном запросе, приджойнив по дате одну и ту же табличку , ну от этого мне кажеться быстрее работать не будет.У кого-нибудь есть другие варианты?
     
  4. armadillo

    armadillo Активный пользователь

    С нами с:
    6 апр 2007
    Сообщения:
    2.380
    Симпатии:
    0
    Адрес:
    Russia, Moscow
    человек знает что такое count, но использует num_rows в сочетании с group by.
    Чего я не понимаю? 0_0

    перепиши все в один запрос с count(distinct ip) и т.п..

    Варианты конечно есть. Только надо расписать на русском что хотим получить.
     
  5. GvOzD

    GvOzD Активный пользователь

    С нами с:
    16 фев 2007
    Сообщения:
    103
    Симпатии:
    0
    armadillo
    Спасибо большое , я исправлюсь ) о функцию count знал поверхностно
     
  6. armadillo

    armadillo Активный пользователь

    С нами с:
    6 апр 2007
    Сообщения:
    2.380
    Симпатии:
    0
    Адрес:
    Russia, Moscow
    в любом случае стоит расписать на русском подробно
     
  7. GvOzD

    GvOzD Активный пользователь

    С нами с:
    16 фев 2007
    Сообщения:
    103
    Симпатии:
    0
    Помогите с написанием запроса , вот сам запрос:

    [sql]SELECT DATE_FORMAT(stats.date,'%Y-%m-%d'),COUNT(*),COUNT(DISTINCT stats.ip),COUNT(bot.agent) FROM stats
    LEFT JOIN stats AS bot ON (stats.id=bot.id)
    WHERE LOCATE('Yandex',bot.agent)>0
    GROUP BY DATE_FORMAT(stats.date,'%Y-%m-%d')[/sql]

    На выходе получаю всего одну запись удовлетворяющую условию WHERE ,а хотел бы получить все данные из первой таблицы и если есть данные из второй , ну а если нет соответственно NULL.И что бы COUNT(bot.agent) выводил число записей не равные NULL , тоесть количество по полю агент , где найдена подстрока Yandex
     
  8. armadillo

    armadillo Активный пользователь

    С нами с:
    6 апр 2007
    Сообщения:
    2.380
    Симпатии:
    0
    Адрес:
    Russia, Moscow
    это надо делать при добавлении записи. В таком виде будет абсолютно неработоспособно при реальной нагрузке.

    тут тоже стоит придумать что-то, связанное с индексом.


    делай последовательно, сначала без джойна, тем более что мы не знаем что у тебя в статс и т.п.
     
  9. GvOzD

    GvOzD Активный пользователь

    С нами с:
    16 фев 2007
    Сообщения:
    103
    Симпатии:
    0
    armadillo
    Да можно на этапе добавления записи делать проверку бот это или юзер , тогда вывод из базы становиться элементарным , но увеличиваем в нагрузке клиентскую часть скрипта.Или это не страшно?
     
  10. GvOzD

    GvOzD Активный пользователь

    С нами с:
    16 фев 2007
    Сообщения:
    103
    Симпатии:
    0
    На этапе добавления записи сделал следующую проверку на поискового бота:

    PHP:
    1. if (strstr($_SERVER['HTTP_USER_AGENT'], 'Yandex')){ $bot='Yandex';$bot_ip=$IP;}
    2. else if (strstr($_SERVER['HTTP_USER_AGENT'], 'Googlebot')){$bot='Google';$bot_ip=$IP;}
    3. else if (strstr($_SERVER['HTTP_USER_AGENT'], 'Mediapartners-Google')){$bot='Mediapartners-Google (Adsense)';$bot_ip=$IP;}
    4. else if (strstr($_SERVER['HTTP_USER_AGENT'], 'Slurp')){$bot='Hot&nbsp;Bot&nbsp;search';$bot_ip=$IP;}
    5. else if (strstr($_SERVER['HTTP_USER_AGENT'], 'WebCrawler')){$bot='WebCrawler&nbsp;search';$bot_ip=$IP;}
    6. else if (strstr($_SERVER['HTTP_USER_AGENT'], 'ZyBorg')){$bot='Wisenut&nbsp;search';$bot_ip=$IP;}
    7. else if (strstr($_SERVER['HTTP_USER_AGENT'], 'scooter')){$bot='AltaVista';$bot_ip=$IP;}
    8. else if (strstr($_SERVER['HTTP_USER_AGENT'], 'StackRambler')){$bot='Rambler';$bot_ip=$IP;}
    9. else if (strstr($_SERVER['HTTP_USER_AGENT'], 'Aport')){$bot='Aport';$bot_ip=$IP;}
    10. else if (strstr($_SERVER['HTTP_USER_AGENT'], 'lycos')){$bot='Lycos';$bot_ip=$IP;}
    11. else if (strstr($_SERVER['HTTP_USER_AGENT'], 'WebAlta')){$bot='WebAlta';$bot_ip=$IP;}
    12. else if (strstr($_SERVER['HTTP_USER_AGENT'], 'yahoo')){$bot='Yahoo';$bot_ip=$IP;}
    13. else if (strstr($_SERVER['HTTP_USER_AGENT'], 'msnbot')){$bot='msnbot/1.0';$bot_ip=$IP;}
    14. else if (strstr($_SERVER['HTTP_USER_AGENT'], 'ia_archiver')){$bot='Alexa search engine';$bot_ip=$IP;}
    15. else if (strstr($_SERVER['HTTP_USER_AGENT'], 'FAST')){$bot='AllTheWeb';$bot_ip=$IP;}
    И построение отчёта не составило труда , даже не понадобился JOIN , всё сделал с помощью COUNT(DISTINCT ).
    armadillo Спасибо.
     
  11. md5

    md5 Активный пользователь

    С нами с:
    29 янв 2007
    Сообщения:
    250
    Симпатии:
    0
  12. topas

    topas Активный пользователь

    С нами с:
    16 авг 2006
    Сообщения:
    2.258
    Симпатии:
    36
    md5
    +1, посетила та же мысль
     
  13. GvOzD

    GvOzD Активный пользователь

    С нами с:
    16 фев 2007
    Сообщения:
    103
    Симпатии:
    0
    Количество кода из-за этого не уменьшиться ))) Так что в этом случае цикл неуместен.....
     
  14. topas

    topas Активный пользователь

    С нами с:
    16 авг 2006
    Сообщения:
    2.258
    Симпатии:
    36
    вот именно что кода и уменьшиться, хотя это все лирика
    хорошее решение
     
  15. GreatWasp

    GreatWasp Активный пользователь

    С нами с:
    11 янв 2008
    Сообщения:
    94
    Симпатии:
    0
    Адрес:
    Узбекистан, Ташкент.
    Работал раньше в организации. Делали топ рейтинг посещаемости сайтов (www.uz). Намучился там с счетчиками и статистикой по полной..... Если делать по схеме описанной выше то в будущем когда база разрастется все будет жутко тормозить. Поэтому предлагаю хотя бы добавить одну табличку (кэш)
    HOST (ip2long)| COUNT (int 6) | DATE (date)
    При каждом посещении писать в нее одним запросом
    [sql]INSERT INTO `TABLE` (`host`, `count`, `date`) VALUES (.......) ON DUPLICATE KEY UPDATE `count`=`count`+1[/sql]

    В результате получите легкую табличку по хостам. То же самое можно сделать по браузерам и по всему, что интересно. Работает такая схема при выборке очень быстро.
     
  16. mclaud

    mclaud Активный пользователь

    С нами с:
    15 фев 2007
    Сообщения:
    97
    Симпатии:
    0
    Адрес:
    Одесса
    А что http://ua2.php.net/get_browser уже не модно?
    Так вот признак crawler и говорит бот это или не бот, а в поле browser пишет, что это за бот Aport/Google/Yandex и т.д.