[英]What's the best way to structure a log table which shows differently in each view?
我需要設計一個表的結構,該表將存儲項目管理網站的事件/操作日志。
問題是,這些日志的拼寫會根據用戶正在查看的內容而有所不同
例子:
我不確定是否應該將每種不同的可能性存儲在表中,這聽起來不是最佳方法。
對於任何類型的日志,您都可以使用下表結構
CREATE TABLE logs
( id
bigint NOT NULL AUTO_INCREMENT, auto_id
bigint NOT NULL DEFAULT '0', table_name
varchar(100) NOT NULL, updated_at
datetime DEFAULT NULL, updated_by
bigint NOT NULL DEFAULT '0', updated_by_name
varchar(100) DEFAULT NULL,PRIMARY KEY ( id
)) ENGINE=InnoDB AUTO_INCREMENT=3870 默認字符集=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
然后創建另一個表來記錄准確更新了哪些列。
CREATE TABLE logs_entries
( id
bigint NOT NULL AUTO_INCREMENT, log_id
bigint NOT NULL DEFAULT '0', field_name
varchar(100) NOT NULL, old_value
text, new_value
text, PRIMARY KEY ( id
), KEY log_id
( log_id
), CONSTRAINT logs_entries_ibfk_1
FOREIGN KEY ( log_id
) REFERENCES logs
( id
) ON DELETE CASCADE ON UPDATE CASCADE) ENGINE=InnoDB AUTO_INCREMENT=7212 DEFAULT CHARSET=utf8mb3
現在您的表格數據如下所示
現在創建一個數據庫視圖以在簡單查詢中輕松獲取數據
分隔符 $$
ALTER ALGORITHM=UNDEFINED SQL SECURITY DEFINER VIEW view_logs_entries
AS SELECT le
。 id
作為id
, le
。 log_id
AS log_id
, le
。 field_name
AS field_name
, le
。 old_value
作為old_value
, le
。 new_value
作為new_value
, l
。 auto_id
作為auto_id
, l
。 table_name
table_name
, l
。 更新的updated_at
作為更新的updated_at
, l
。 updated_by
AS updated_by
, l
。 updated_by_name
AS updated_by_name
FROM ( logs_entries
le
LEFT JOIN logs
l
ON (( le
. log_id
= l
. id
)))$$
分隔符;
創建數據庫視圖后,您的數據將如下所示,因此現在您可以輕松查詢項目的任何日志
你一定注意到了,我在 logs 表中添加了 updated_by 和 updated_by_name 列,現在有兩種方法可以填充這個 updated_by_name 列
您可以像這樣創建數據庫觸發器,只要在數據庫中添加日志條目,它就會自動插入用戶名。
分隔符 $$
使用YOUR_DATABASE_NAME
CREATE TRIGGER logs_before_insert
BEFORE INSERT ON logs
FOR EACH ROW BEGIN SET new.updated_by_name= (SELECT fullname FROM users WHERE user_id = new.updated_by); 結尾; $$
分隔符;
完成所有這些之后,您可以在任何數據庫表中進行更改時在日志表中插入條目。 在我的情況下,我有 PHP-CodeIgniter 項目,我在我的模型文件中這樣做了,在這里我正在更新我的數據庫的患者表
public function update($id,$data)
{
// Log this activity
$auto_id = $id;
$table_name = 'patients';
$updated_by = @$data['updated_by'];
$new_record = $data;
$old_record = $this->db->where('id',$auto_id)->get($table_name)->row();
$data['updated_at'] = date('Y-m-d H:i:s');
$this->db->where('id', $id);
$return = $this->db->update($table_name,$data);
//my_var_dump($this->db->last_query());
if($updated_by)
{
$this->log_model->set_log($auto_id,$table_name,$updated_by,$new_record,$old_record);
}
return $return;
}
set_log 功能代碼檢查哪些字段實際更改
public function set_log($auto_id,$table_name,$updated_by,$new_record,$old_record)
{
$entries = [];
foreach ($new_record as $key => $value)
{
if($old_record->$key != $new_record[$key])
{
$entries[$key]['old_value'] = $old_record->$key;
$entries[$key]['new_value'] = $new_record[$key];
}
}
if(count($entries))
{
$data['auto_id'] = $auto_id;
$data['table_name'] = $table_name;
$data['updated_by'] = $updated_by;
$this->insert($data,$entries);
}
}
並插入日志功能看起來像這樣
public function insert($data,$entries)
{
$data['updated_at'] = date('Y-m-d H:i:s');
if($this->db->insert('logs', $data))
{
$id = $this->db->insert_id();
foreach ($entries as $key => $value)
{
$entry['log_id'] = $id;
$entry['field_name'] = $key;
$entry['old_value'] = $value['old_value'];
$entry['new_value'] = $value['new_value'];
$this->db->insert('logs_entries',$entry);
}
return $id;
}
return false;
}
您需要將數據與顯示分開。 在您的日志中,存儲完整信息(用戶 xxx 已刪除項目 2881)。 在您的日志查看器中,您可以根據需要進行替換以使其更具可讀性。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.