Добро пожаловать на Pro Pawn - Портал о PAWN-скриптинге.
Показано с 1 по 5 из 5
  1. #1
    Аватар для 123
    Пользователь

    Статус
    Оффлайн
    Регистрация
    09.02.2014
    Сообщений
    93
    Репутация:
    8 ±

    Статистика онлайна за N дней

    Конечно же, рано или поздно встает вопрос о контроле посещаемости у администрации, у лидеров, и других ключевых персонажей RP сервера. Так вот, как же это реализовать?

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

    Пример конечно рабочий, но, как мне кажется, неправильный. Его нельзя расширить (вдруг мне понадобится статистика за месяц?), да и нагромождение виде 7 лишних полей - далеко не лучший вариант.

    На ум приходит второй, более "правильный" со всех аспектов вариант.

    Создать таблицу stats с полями -
    id
    user
    enter_game - время авторизации
    left_game - время выхода

    И методом простого расчета left_game - enter_game - получаем время игры за одну игровую сессию.
    Но встает ряд сложностей в плане реализации.

    Например, мне нужно получить онлайн за последние 7 дней. Как составить такой запрос?
    Допустим, я составил правильный запрос и получил данные. Теперь нужно как-то склеить все игровые сессии за каждый день и вывести в диалог по шаблону:

    (дата) - (время в игре)

    На что у меня тоже нет никаких мыслей.

    Может кто нибудь сталкивался, и знает как это все решается?

  2. #2
    Аватар для Kucklovod00
    Пользователь

    Статус
    Оффлайн
    Регистрация
    20.12.2017
    Сообщений
    36
    Репутация:
    0 ±
    Лучше создать отдельную таблицу и выводить результат по идентификатору/нику игрока. Если результатов будет более, чем 7 (или 30), то лишние строки удаляем. Думаю, в отдельной таблице лучше хранить статистику посещения только лидеров и администраторов, а для игроков либо не хранить, либо хранить в переменных на игрока.

    Запрос для вывода статистики - SELECT. INSERT - если за сегодняшний день записи нет и UPDATE если игрок зашел более одного раза и проиграл какое-то время

  3. #3
    Аватар для DeimoS
    Модератор?

    Статус
    Оффлайн
    Регистрация
    27.01.2014
    Адрес
    Восточный Мордор
    Сообщений
    5,588
    Репутация:
    1984 ±
    Всё зависит от того, сколько дней ты хочешь логировать и какие критерии для логирования у тебя есть (исключать ли время в АФК и т.п.). Под каждый случай стоит выбирать свой алгоритм, который будет потреблять минимум ресурсов и давать большую скорость при выборке данных. Иначе всё может кончиться не очень хорошо.


    Цитата Сообщение от 123 Посмотреть сообщение
    да и нагромождение виде 7 лишних полей - далеко не лучший вариант.
    Нет никакого "нагромождения" от того, что у тебя будет 7 "лишних" полей. Наоборот, в результате у тебя в таблице будет, как минимум, на 6 записей меньше для каждого из админов. Соответственно, скорость работы с данными будет выше, так как MySQL будет быстрее находить (или не находить) нужные строки. Для MySQL нормой являются таблицы и с нескольким десятком столбцов, и с сотней. Главное, чтоб это было оправдано твоими нуждами и на деле не было так, что есть более оптимальный вариант с 3-мя столбцами вместо 150-и.

    Цитата Сообщение от 123 Посмотреть сообщение
    На ум приходит второй, более "правильный" со всех аспектов вариант.

    Создать таблицу stats с полями -
    id
    user
    enter_game - время авторизации
    left_game - время выхода

    И методом простого расчета left_game - enter_game - получаем время игры за одну игровую сессию.
    Но встает ряд сложностей в плане реализации.

    Например, мне нужно получить онлайн за последние 7 дней. Как составить такой запрос?
    Допустим, я составил правильный запрос и получил данные. Теперь нужно как-то склеить все игровые сессии за каждый день и вывести в диалог по шаблону:

    (дата) - (время в игре)

    На что у меня тоже нет никаких мыслей.
    Как-то так
    PHP код:
    SELECT userenter_time, IF(left_game 0, (left_game-enter_game), (NOW()-enter_game)) AS online_time FROM table_name 
    Вернёт время сессии в секундах (возможно, понадобится сделать дополнительную обёртку в UNIX_TIMESTAMP для полей "left_game" и "enter_game" при вычислении). Условие "IF" там нужно для того, чтоб на случай, если в момент обращения к таблице, какой-то из админов был в сети, то для него вывело бы время текущей сессии, а не белиберду. Можно вместо "IF" сделать условие для выборки в WHERE, исключая такие записи. Так же можно сделать статистику за все дни (просто не удалять записи), но тогда лучше создать вторую таблицу, в которую раз в n-дней (например, раз в неделю/месяц или просто когда в таблице будет определённое число записей) переносить более старые записи, дабы количество столбцов не влияло ни на время выборки, ни на время обновления данных (вторую таблицу можно так же, со временем, поделить ещё на определённое количество таблиц. Или просто чистить уж очень старые записи). Так же можно объединить твой первый вариант (с n-числом полей под определённый день) и второй, просто создавая новую строку, когда все столбцы заполнятся, а не перезаписывая старые столбцы (только тогда нужно продумать алгоритм хороший для контроля даты. Например, один столбец выделить под дату первого столбца с временем онлайна. А потом сверять текущую дату с тем столбцом и если, например, с момента создания строки прошло 3 дня, а ты записывал информацию всего в первый день (2-ой столбец онлайна содержит нуль), то так же создаёшь новую строку и пишешь информацию туда, а прошлая строка пусть с нулями будет).

    Ну а вообще, вот эти функции тебе в помощь - http://www.mysql.ru/docs/man/Date_an...functions.html. Например, если нужно отсортировать все данные за текущий месяц, а у тебя нет соответствующего столбца (ты хранишь только дату), можно сделать так:
    PHP код:
    ... WHERE DATE_FORMAT(столбец_с_датой'%m.%Y') = '11.2018' 
    и ты получишь нужные данные.
    Последний раз редактировалось DeimoS; 04.11.2018 в 22:27.
    Связаться со мной в VK можно через личные сообщения этой группы
    Заказы не принимаю

    Широко известно, что идеи стоят 0.8333 цента каждая (исходя из рыночной цены 10 центов за дюжину).
    Великих идей полно, на них нет спроса.
    Воплощение идеи в законченную игру требует долгой работы,
    таланта, терпения и креативности, не говоря уж о затратах денег, времени и ресурсов.
    Предложить идею просто, воплотить – вот в чём проблема

    Steve Pavlina

  4. #4
    Аватар для 123
    Пользователь

    Статус
    Оффлайн
    Регистрация
    09.02.2014
    Сообщений
    93
    Репутация:
    8 ±
    Цитата Сообщение от Kucklovod00 Посмотреть сообщение
    Думаю, в отдельной таблице лучше хранить статистику посещения только лидеров и администраторов, а для игроков либо не хранить, либо хранить в переменных на игрока.
    Почему? Таблица для того и создается, что бы не нагромождать основную таблицу, и увеличить её отзывчивость. И если и вести такую статистику - то вести её для всех, тогда будет намного проще отбирать кандидатов на тоже лидерство или администрирование. А таблицу чистить раз в месяц или неделю, по потребности.

    Цитата Сообщение от DeimoS Посмотреть сообщение
    PHP код:
    SELECT userenter_time, IF(left_game 0, (left_game-enter_game), (NOW()-enter_game)) AS online_time FROM table_name 
    Хорошо, с этим понятно. Прежде всего, меня интересует как отсортировать этот запрос и получать результат на каждый день из нужного периода (поскольку сейчас, записывается каждая игровая сессия, а их за один день может быть > 1. Их нужно как-то склеить).

  5. #5
    Аватар для DeimoS
    Модератор?

    Статус
    Оффлайн
    Регистрация
    27.01.2014
    Адрес
    Восточный Мордор
    Сообщений
    5,588
    Репутация:
    1984 ±
    SUM?

    PHP код:
    SELECT SUM(left_game-enter_game) AS online_time FROM table_name WHERE user '123' AND DATE_FORMAT(enter_game'%d.%m.%Y') = '05.11.2018' 
    Покажет сколько ты отыграл за сегодня

    Хотя если тебе не нужна подробная статистика, то проще каждый день создавать 1 поле и к столбцу с онлайном прибавлять значение.
    То бишь:
    PHP код:
    id account_id date online_uptime 
    При авторизации записываешь gettime() в переменную. При выходе (а заодно и каждые 5-10 минут, дабы не потерять статистику в случае вылета сервера) делаешь запрос в базу, проверяя существования строки для игрока с сегодняшней датой, возвращая ID строки, если она найдена.
    Если найдено:
    PHP код:
    UPDATE table SET online_uptime online_uptime+/*gettime()-время_из_переменной*/ WHERE id /*возвращённый_ID*/ 
    Если не найден - создаёшь новую запись.

    Такой вариант гораздо практичнее будет в твоём случае.
    Последний раз редактировалось DeimoS; 05.11.2018 в 04:48.
    Связаться со мной в VK можно через личные сообщения этой группы
    Заказы не принимаю

    Широко известно, что идеи стоят 0.8333 цента каждая (исходя из рыночной цены 10 центов за дюжину).
    Великих идей полно, на них нет спроса.
    Воплощение идеи в законченную игру требует долгой работы,
    таланта, терпения и креативности, не говоря уж о затратах денег, времени и ресурсов.
    Предложить идею просто, воплотить – вот в чём проблема

    Steve Pavlina

 

 

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •