[MySQL] Лог действий пользователя

Статус
Закрыто для дальнейших ответов.

Indev29

Just Code...
Регистрация
15.08.2012
Сообщения
370
Здравствуйте форумчане! Вопрос следующий: как хранить в БД лог действий пользователя (с возможностью просмотра юзером на веб странице)? Какова структура таблицы? Заранее спасибо!
 

Кирилл Меньков

Well-Known Member
Регистрация
17.02.2011
Сообщения
93
Смотря каких действий?
Ясное дело, надо хранить дату + время, само действие.

Я бы сделал 2 таблицы:
1. Хранится список ВСЕХ возможных действий
2. Список с ид юзера, ид действия, время действия.

При малом количестве действий их можно хранить в виде констант в модели, например.
 

Volter9

defined('SURRENDER') or die(); // StarWars
Регистрация
27.05.2012
Сообщения
1 145
Ну приблизительно такая:
// id - userid - userip - userurl - usermethod - uservars - usercookies
Короче так:
id - это уникальный номер
userid - это если есть аккаунт на сайте, и это его id (аккаунта)
userurl - адрес на вашем сайте где он сейчас находится
usermethod - это метод ($_GET или $_POST)
uservars - это переменные которые у него есть из глобального массива $_GET или $_POST
usercookies (не обязательно) - Куки пользователя.
 

Indev29

Just Code...
Регистрация
15.08.2012
Сообщения
370
Разобрался, спасибо! Теперь другой вопрос, как построить таблицу, в которой необходимо записать 40 различных показателей пользователя, в 8-ми различных ситуациях. Тоесть: есть ситуация1: показатель1, показатель 2. И так далее.
 

Volter9

defined('SURRENDER') or die(); // StarWars
Регистрация
27.05.2012
Сообщения
1 145
А что за показатели?
 

Indev29

Just Code...
Регистрация
15.08.2012
Сообщения
370
Что-то вроде характеристик. Вобщем описать можно гораздо проще на языке фентези) Ну допустим у нас есть 8 персонажей(или как их там, команда вобщем), у каждого есть 40 навыков. У меня также, только немного не то) Но структура такая же думаю будет.

Сейчас сделано 8 таблиц, Под каждую ситуацию по одной, есть ли смысл делать 40 колонок (под каждый показатель)? Мне кажется это немного не айс)
 

Volter9

defined('SURRENDER') or die(); // StarWars
Регистрация
27.05.2012
Сообщения
1 145
Сделай одну таблицу с разными характеристиками и присвой каждой характеристики тип.
 

Indev29

Just Code...
Регистрация
15.08.2012
Сообщения
370
И потом получится, что те восемь таблиц под ситуации содержат таки 40 столбцов? Просто с id показателя (характеристики)?
 

Volter9

defined('SURRENDER') or die(); // StarWars
Регистрация
27.05.2012
Сообщения
1 145
И потом получится, что те восемь таблиц под ситуации содержат таки 40 столбцов? Просто с id показателя (характеристики)?
Ага. Лучше ж 40 столбцов и 2 таблицы, чем 8 таблиц и 8 столбцов в каждой + в каждой по одному правилу характеристики.
 

Indev29

Just Code...
Регистрация
15.08.2012
Сообщения
370
Ясно, так я и думал. Спасибо.
 

mrlasking

$_GET['rich'] or die('trying');
Регистрация
22.05.2012
Сообщения
323
Хм, что-то как-то усложняете, по моему.

По посту вольтера - очень редко когда, нужно хранить пост и гет значения пользователя в логах. Это какой-то уж совсем детальный лог. :huh:

По фентези игрушкам, а как я понял, автор занимается разработкой именно игры, лучше делать отдельные таблицы под разные виды действий. Это взгляд в будущее, представьте, что у вас одна база логов, в которой неимоверное количество столбцов и строк, (а строк там будет до апупенения просто) и модераторы (а влюбой игре должны быть модераторы/хранители/админы как не назови) будут дергать эту МЕГО базу что б посмотреть логи боев перса, потом логи сделок потом логи продажи вещей в магазин и логи обмена на рынке :blink: . Молчу про логи полученых вещей в луте, опыта, травм и прочих атрибутов игр. Это абсурдно - хранить все в одном месте.

1. Логи должны быть разделены. Пишите класс или функцию (в зависимости от подхода) которая на вход получает параметры логирования и полные данные, а потом распихивает по нужным таблицам.
2. Таблицы актуальных логов (которые часто дергают и шерстят модеры) держать надо в ограниченном виде, напримерЖ за три месяца логи хранить. Далее сливать все в суровые многометровые таблицы-хранилища, откуда при редкой надобности поднимаются старые логи пользователей...


Могу добавить, что слова не на голых домыслах основаны, непосредственно участвую в разработке браузерной игры, так что пишу из личного опыта. :)

UP: По ситуации со статами, что мешает сделать такой подход:
1. Таблица логирования статов: user_id, condition, stats_array. где
user_id - всем понятно)
condition - ид 1..8 - варианты ситуации,
stats_array = строка вида 1:2:12:3:21:23:....:72 (*)
2. функция преобразования строки (*) в массив вида:
Код:
Array (
  "poison" => 1,
  "troll_power" => 2,
  "facepalm_skil" => 12,
  ....
  "pickup_master" => 72
)
Получите три столбика, шустрые запросы и быструю работу...

=)
 

Volter9

defined('SURRENDER') or die(); // StarWars
Регистрация
27.05.2012
Сообщения
1 145
Я писал это не обосновано, т.к. не знал чем занимается ТС (так, то знал, а вот не знал подробности задачи.), написал такой вариант, т.к. думал что это нужно для наблюдения над юзером (не игроком), который бродит по тихим страницам веб-деревни, в поисках своей заветной статьи))
 

mrlasking

$_GET['rich'] or die('trying');
Регистрация
22.05.2012
Сообщения
323
Лучше ж 40 столбцов и 2 таблицы, чем 8 таблиц и 8 столбцов в каждой
В корне не верно, при подходе к разработке игры. Даже имея всего пару десятков активных пользователей, всего через пару суток, эти таблицы превратятся в помойку которая будет подвешивать любой скрипт на десяток другой секунд и заставлять разработчика рвать на себе волосы, а игрока уходить из тормознутой игрушки =)


UP: [member=Volter9], понял) Ну, в играх все немного по-другому)
 

Volter9

defined('SURRENDER') or die(); // StarWars
Регистрация
27.05.2012
Сообщения
1 145
Лучше ж 40 столбцов и 2 таблицы, чем 8 таблиц и 8 столбцов в каждой
В корне не верно, при подходе к разработке игры. Даже имея всего пару десятков активных пользователей, всего через пару суток, эти таблицы превратятся в помойку которая будет подвешивать любой скрипт на десяток другой секунд и заставлять разработчика рвать на себе волосы, а игрока уходить из тормознутой игрушки =)


UP: [member=Volter9], понял) Ну, в играх все немного по-другому)
Я сам не давно игру делал, только не браузерку, а на иФон.
Там немного по другому.
 

Indev29

Just Code...
Регистрация
15.08.2012
Сообщения
370
[member=mrlasking], а то, что в итоге получится 8-мь строк на каждого пользователя, это не страшно?)
 

Volter9

defined('SURRENDER') or die(); // StarWars
Регистрация
27.05.2012
Сообщения
1 145
Я так не думаю, что 8 таблиц и так на каждого пользователя.
Зато сортировка будет: бах... Заходишь на страницу с боями, нашел че надо... бах... На другую.

Так хоть будет 8 логов, и их просматривать будет легче).
 

Indev29

Just Code...
Регистрация
15.08.2012
Сообщения
370
Возникла другая проблема, как теперь вытащить это все средствами пхп.
Таблица posts:
mes_id Ид сообщения rec_id Ид получателя mes_time Время сообщения check Прочитано (0 - нет, 1 - да) mes_text Текст сообщения
1 1 0 0 Текст1
2 1 0 0 Текст2

Получается вытащить только строку с Текстом1.

Код:
<?
$id = 1;
$answer = 'text';
include("bd.php"); //Тут подключаемся к бд и выбираем базу;
$result = mysql_query("SELECT mes_text, mes_time FROM posts WHERE rec_id = $id");
$array = mysql_fetch_array($result);
$i = 0;
while (!empty($answer))
{
$answer = $array[$i];
echo $answer;
$i++;
}
?>
 

mrlasking

$_GET['rich'] or die('trying');
Регистрация
22.05.2012
Сообщения
323
[member=Indev],
mrlasking, а то, что в итоге получится 8-мь строк на каждого пользователя, это не страшно?)
Ну, во-первых, в той ситуации что описывали вы (есть пользователь, набор из 8ми ситуаций, и набор статов) - запись будет только одна на каждое действие, ид юзера, ид от 1 до 8 - вариант состояния и третье значение - набор параметров. Я это уже описал выше. Перечитайте пожалуйста ответ )



Возникла другая проблема...
Получите ответ в массив и идите по нему циклом foreach.


Пример функции query, простейший, но эффективный:

Код:
function query($query, $getOne = false) {
$query = eregi_replace("\n", "", $query);
$query = eregi_replace("\r", "", $query);
$query = trim( $query );
$newQuery = strtolower( $query );
list( $queryType ) = split( "\ ", $newQuery );
$queryResult = mysql_query( $query );
$result = false;
if ( $queryType == "select" ) {
	 $data = Array();
	 while ( $row = mysql_fetch_assoc ( $queryResult ) ) {
		 $data[] = $row;
	 }

	 $result = $data;
} else if ( $queryType == "insert" ) {
	 $result = mysql_insert_id ();
} else{
	 $result = true;
}
return $result;
}
Пример прохода по массиву, без всяких счетчиков, вайлов и прочей ереси )
Код:
$result = query("SELECT mes_text, mes_time FROM posts WHERE rec_id = 1");
if (count($result) > 0){
foreach ($result as $key=>$val){

echo $val["mes_text"];
}
}
mes_id Ид сообщения rec_id Ид получателя mes_time Время сообщения check Прочитано (0 - нет, 1 - да) mes_text Текст сообщения
1 1 0 0 Текст1
2 1 0 0 Текст2


В результате вы получите массив вида:
Код:
Array (
[0] => Array (
"mes_id" => 1,
"rec_id" => 1,
"mes_time" => 0,
"check" => 0,
"mes_text" => "Текст1"
),
[1] => Array (
"mes_id" => 2,
"rec_id" => 1,
"mes_time" => 0,
"check" => 0,
"mes_text" => "Текст2"
)
);
А после прохода по нему вывод текста сообщений.
 

Indev29

Just Code...
Регистрация
15.08.2012
Сообщения
370
Все, решил так:
Код:
<?
$rows = mysql_num_rows($q);
$fields = mysql_num_fields($q);
for ($c=0; $c<$rows; $c++) {
for ($cc=0; $cc<$fields; $cc++) {
echo mysql_result($q, $c, $cc)."\t";
echo "\n";
}
}
?>
Спасибо!
 

mrlasking

$_GET['rich'] or die('trying');
Регистрация
22.05.2012
Сообщения
323
Два раза перезаходил, думал все-таки промолчать, но видимо не могу сдержаться...

Камрад Максим, (надеюсь не ошибся в имени), привыкайте кодить грамотно) Зачем использовать два цикла со счетчиками там, где можно использовать один foreach ? Если у вас есть возможность не писать лишнее echo - не делайте этого.

Себя не причисляю к великим профи, но, по моему мнению, писать :
Код:
$result = query("SELECT mes_text, mes_time FROM posts WHERE rec_id = 1");
if (count($result) > 0){
foreach ($result as $key=>$val){
echo $val["mes_text"];
}
}
(функция query в этом посте)
более функционально и оптимально. Да и понятнее, опять же по моему, чем:
Код:
$rows = mysql_num_rows($q);
$fields = mysql_num_fields($q);
for ($c=0; $c<$rows; $c++) {
for ($cc=0; $cc<$fields; $cc++) {
echo mysql_result($q, $c, $cc)."\t";
echo "\n";
}
}
Хотелось бы уже и мне услышать мнение наших гуру по этому поводу, может вообще раскритикуют в пух и прах. Тогда, Максим, мы оба почерпнем что-то новое и повысим скил) :cool:
 
Статус
Закрыто для дальнейших ответов.
Верх Низ