MySQL запрос, если заявление - PullRequest
       30

MySQL запрос, если заявление

0 голосов
/ 20 декабря 2009

Для простоты, скажем, я делаю основной счетчик просмотров страниц в php, который хранит счетчики для каждой страницы в таблице mysql. В таблице было 2 столбца: PAGE_ID и COUNT.

Я добавил следующий код на каждую страницу:

$query = "INSERT INTO table VALUES ('$page_id', '1')
         ON duplicate KEY UPDATE COUNT=COUNT+1";

$result = mysqli_query($cxn, $query);

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

Некоторые страницы получали слишком много просмотров, я подозревал дубликаты, поэтому я начал регистрировать IP-адреса и пользовательские агенты. Оказывается, примерно в 10% случаев IP запускает счетчик для одной и той же страницы 2-3 раза за несколько минут.

Первый вопрос Что может быть причиной дубликатов? Похоже, что проблема возникает в основном с IE8 и Safari, но у меня также есть хотя бы один случай, когда это происходит с IE7 и IE6. Любая известная проблема с сессиями php? Должен ли я использовать куки вместо этого?

Часть 2: Я изменил свою таблицу так, чтобы она теперь сохраняла последнюю метку времени Unix и последний IP, который вызвал счетчик.

Я хочу изменить свой запрос так, чтобы перед запуском "COUNT = COUNT + 1" он проверял следующее:

If the current IP is the same as the last stored IP for this page {

     check that it's been at least 5 minutes before doing COUNT=COUNT+1

} else { COUNT=COUNT+1; }

Второй вопрос Как мне написать это в запросе mysql, сохранив мой оператор «ON duplicate KEY»?

Я понимаю, что это утверждение не будет на 100% точным, но пока я не смогу выяснить, почему сессия не работает, это будет работать. Мой сайт имеет низкий трафик, и я редко получаю более 1 посетителя на одной странице в течение 5 минут.

Спасибо

Ответы [ 4 ]

2 голосов
/ 20 декабря 2009

Я бы посоветовал вам попытаться выяснить, можете ли вы исправить PHP, но игнорируйте это. Вы можете сохранить unixtimestamp, деленную на 300 (т.е. с 5-минутными интервалами)

$ query = "Вставить в другие значения таблицы ('$ page_id', '$ IP_ADDRESS', (UNIX_TIMESTAMP (NOW ()) / 300))";

Если количество обновленных записей равно 0, вам не нужно обновлять счетчик страниц.

1 голос
/ 20 декабря 2009

1. Что может быть причиной дубликатов?

Некоторые страницы получали слишком много просмотров, я подозревал дубликаты, поэтому я начал регистрировать IP-адреса и пользовательские агенты. Оказывается, примерно в 10% случаев IP запускает счетчик для одной и той же страницы 2-3 раза за несколько минут.

Нет способа узнать, находится ли хост, запрашивающий страницу, за маршрутизатором NAT - для вас запрос будет иметь тот же IP-адрес, но на самом деле это другой хост. Файл cookie или сеанс помогут вам изолировать данные для каждой рабочей станции, хотя мне интересно, когда вы запишете информацию в базу данных.

2. Как мне написать это в запросе mysql, сохранив мой оператор «ON duplicate KEY»?

Я не вижу необходимости в COUNT = COUNT + 1, потому что в SQL есть функция COUNT:

  SELECT page_id,
         COUNT(*) 'num_hits'
    FROM ZZZ_NETWORK
   WHERE page_id = ?
GROUP BY page_id

Если вы использовали следующую структуру для ZZZ_NETWORK:

  • page_id, первичный ключ
  • ip_address, первичный ключ
  • метка времени, первичный ключ

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

Через месяц в моей таблице будут тысячи строк, если я буду использовать одну строку на просмотр страницы.

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

Я не понимаю, как это могло бы гарантировать, что я никогда не получу дубликат.

Отметка времени включает в себя как дату (25 декабря 2009 г.), так и время (07:00:00 AM). Некоторые типы данных datetime сокращаются до доли секунды. Это делает почти невозможным иметь одинаковую дату и время для данного page_id с заданным IP-адресом - я не могу достаточно быстро нажать кнопку обновления, даже если бы захотела. Поэтому записи никогда не могут быть дубликатами, потому что последний из трех столбцов будет каждый раз иметь разное значение (без каламбура).

0 голосов
/ 21 декабря 2009

Я думаю, что нашел способ решить проблему с сессией. На самом деле, я переключился с сессии на куки.

Многие мои страницы получают просмотры через iframe. Iframe вызывал проблему с браузерами IE. IE не смог прочитать данные cookie из iframe, если я не добавил заголовок p3p.

Я добавил заголовок p3p, и теперь он, кажется, работает правильно. Я так устал от Microsoft и их идеи безопасности. Я также понятия не имею, что такое p3p, но вот как это выглядит в php.

header ( "p3p:CP=\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\"");
0 голосов
/ 20 декабря 2009

То, что вы ищете, это CASE утверждение: http://dev.mysql.com/doc/refman/5.0/en/case-statement.html

Пример CASE оператора:

SELECT name,
       (CASE WHEN is_happy THEN "Happy!"
        ELSE "sad." END) as happiness 
FROM user_state;

Они также могут использоваться в UPDATE и INSERT.

Я подозреваю, что вместо этого вы хотите посмотреть на IE. У меня были подобные проблемы в прошлом, и я вынужден был использовать JavaScript для отмены отказов кликов. Я не уверен, что это были пользователи IE, дважды щелкающие мышью, или это был странный IE.

...