簡體   English   中英

構建在每個視圖中顯示不同的日志表的最佳方法是什么?

[英]What's the best way to structure a log table which shows differently in each view?

我需要設計一個表的結構,該表將存儲項目管理網站的事件/操作日志。

問題是,這些日志的拼寫會根據用戶正在查看的內容而有所不同

例子:

  • 在概覽中,操作可能會說“John F. 刪除了項目 #2881”
  • 在單項頁面上,會顯示“John F. deleted this item”
  • 如果當前用戶是 John F. 它會拼寫“你刪除了這個項目”

我不確定是否應該將每種不同的可能性存儲在表中,這聽起來不是最佳方法。

對於任何類型的日志,您都可以使用下表結構

CREATE TABLE logsid 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作為idle log_id AS log_idle field_name AS field_namele old_value作為old_valuele new_value作為new_valuel auto_id作為auto_idl table_name table_namel 更新的updated_at作為更新的updated_atl 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 列

  1. 您可以在每個日志條目上編寫查詢以獲取用戶名並存儲它(不推薦)
  2. 您可以制作數據庫觸發器來填充此列(推薦)

您可以像這樣創建數據庫觸發器,只要在數據庫中添加日志條目,它就會自動插入用戶名。

分隔符 $$

使用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM