Я ищу способ сделать простой журнал событий для моих таблиц. У меня есть несколько таблиц, которые могут быть изменены различными пользователями, и я хочу отслеживать:
- who made the change
- when
- what was before update
- what is the new value
- which table and which record & column
что-то вроде будет здорово:
20:00:00 | john | update | products | 113 | product_name | "xbox" | "xbox 360"
20:00:10 | jim | update | products | 113 | product_name | "xbox 360" | ""
20:01:00 | jim | delete | products | 113
Итак, я прочитал, что триггеры могут быть ответом, но насколько я читаю, мне кажется, что мне нужна полная таблица для каждого столбца, который я хочу отслеживать. Триггеры не идеально подходят для этой работы также потому, что я хочу записать, кто внес изменение, и из того, что я прочитал, это невозможно.
Я подумал о создании 3 различных функций для CRUD (вставка, обновление, удаление) и непосредственно перед выполнением запроса, чтобы проверить, что изменилось, и создать журнал, а затем выполнить запрос. Но отсюда это кажется очень медленным и сложным.
Есть ли другой лучший способ?
Спасибо
Хорошо, я снова проверил триггеры, и это не то, что я искал, поэтому я написал простые функции, которые будут проверять для каждого запроса, который вы хотите регистрировать, если новые значения различны, и если так - он регистрирует его.
Основная проблема в том, что я ее не измерял, но она явно медленнее.
сначала вам нужно создать новую таблицу mysql следующим образом:
- id (a_i, основной)
- дата создания (дата / время)
- user_id (int)
- table_name (tinytext)
- record_id (int)
- имя_ ячейки (tinytext)
- action_type (tinytext)
- old_value (текст)
- новое_значение (текст)
после этого напишите функции. Я еще не писал разделы «INSERT» и «DELETE», но думаю, мне должно быть намного легче.
function log_query($action_type, $table, $values, $parameters){
if ($action_type == 'UPDATE'){
log_updates($action_type, $table, $values, $parameters);
$query = "UPDATE $table SET ";
foreach ($values as $key => $value){
$query .= $key."='";
$query .= $value."', ";
}
unset($value);
$query = substr($query, 0, -2);
$query .= ' WHERE ';
foreach ($parameters as $key => $value){
$query .= $key."='";
$query .= $value."' AND ";
}
unset($value);
$query = substr($query, 0, -4);
$result = mysql_query($query);
}
}
и:
function log_updates($action_type, $table, $values, $parameters){
$where = " WHERE ";
$user_id = '1234'; //example
foreach ($parameters as $key => $value){
$where .= $key."='";
$where .= $value."' AND ";
}
unset($value);
$where = substr($where, 0, -4);
foreach ($values as $key => $value){
$result = mysql_query("SELECT $key, id FROM $table $where");
$row = mysql_fetch_row($result);
$old_value = $row[0];
$record_id = $row[1];
if ($action_type == 'UPDATE'){
if ($old_value != $value){
$logger = mysql_query("INSERT INTO auditing (event_date, action_type, user_id, table_name, record_id, cell_name, old_value, new_value)
VALUES (NOW(), '$action_type', $user_id, '$table', '$record_id', '$key', '$old_value', '$value')");
if (!$logger) echo mysql_error();
}
}
}
unset($value);
}
для вызова функций вам нужно сначала упорядочить параметры, чтобы найти конкретную строку, и новые значения в массивах, а после этого вызвать функцию log_query:
$update = Array('name' => 'barbara', 'description' => 'new name');
$parameters = Array('id' => '1', 'name' => 'barbi');
log_query('UPDATE', 'checktable', $update, $parameters);
Это действительно проверит, изменилось ли «имя» и изменилось ли описание. для каждого, если он изменится, он вставит новую запись в таблицу «аудита», указав точное изменение.
после регистрации изменений будет запущен запрос на обновление. в нашем примере:
UPDATE checktable SET name='barbara', description='new name' WHERE id='1' AND name='barbi'
надеюсь, это помогает. Это проверено на данный момент и работает. Если будут обновления - выложу здесь.