2016-03-16 50 views
0

我期待在應用程序上保留表格的每一次更新的歷史記錄。我正在使用Laravel,我知道有一些軟件包可以幫助我,但我正在尋找乾淨而快速的東西。用於數據審計的MySQL觸發器或PHP?

我有兩個選擇:

  • MySQL的觸發
  • 通過PHP代碼

我的第一個問題是,哪一個是更快?

我的第二個問題是: 我應該使用的模式是這樣和我所有的表存儲到其中:

CREATE TABLE revisions (
    `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, 
    `revisionable_type` VARCHAR(255) NOT NULL COLLATE 'utf8_unicode_ci', 
    `revisionable_id` INT(11) NOT NULL, 
    `user_id` INT(11) NULL DEFAULT NULL, 
    `key` VARCHAR(255) NOT NULL COLLATE 'utf8_unicode_ci', 
    `old_value` TEXT NULL COLLATE 'utf8_unicode_ci', 
    `new_value` TEXT NULL COLLATE 'utf8_unicode_ci', 
    `created_at` TIMESTAMP NULL DEFAULT NULL, 
    `updated_at` TIMESTAMP NULL DEFAULT NULL 
) 

或者我應該重新建立一個像user_history每個表的「複製」,並添加在respectives列歷史

Users: id, name, surname ... 
Users_history: id, user_id, name, surname ... 
+2

這個問題是非常題外話,因爲它是非常廣泛,可能以意見爲基礎,但觸發是要走的路。因爲它處於數據庫級別,所以更快,更可靠。無論如何,我可能會提供答案,因爲這可能很難正確實施。 – MonkeyZeus

+0

這個問題如何成爲他自己話題的話題?也許這是一個數據庫級別,但這並不意味着MySQL會更快地做到這一點:/您沒有閱讀我的第二個問題 –

回答

0

鑑於此架構:

CREATE TABLE contacts (
    `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, 
    `first_name` VARCHAR(255) NOT NULL COLLATE 'utf8_unicode_ci', 
    `last_name` VARCHAR(255) NOT NULL COLLATE 'utf8_unicode_ci', 
    `updated_by` VARCHAR(255) NOT NULL COLLATE 'utf8_unicode_ci', 
    `updated_at` TIMESTAMP NULL DEFAULT NULL 
) 

我會創建此架構,以及:

CREATE TABLE contacts_audit (
    `id` INT(10) UNSIGNED NOT NULL, 
    `first_name` VARCHAR(255) NOT NULL COLLATE 'utf8_unicode_ci', 
    `last_name` VARCHAR(255) NOT NULL COLLATE 'utf8_unicode_ci', 
    `updated_by` VARCHAR(255) NOT NULL COLLATE 'utf8_unicode_ci', 
    `updated_at` TIMESTAMP NULL DEFAULT NULL, 
    `action` varchar(255) NOT NULL COLLATE 'utf8_unicode_ci' 
) 

然後使用這些觸發器(希望我的觸發語法是不是太生疏):

CREATE TRIGGER contacts_audit_insert 
AFTER INSERT 
    ON users FOR EACH ROW 
BEGIN 
    INSERT INTO contacts_audit (id, first_name, last_name, updated_by, updated_at, action) values (NEW.id, NEW.first_name, NEW.last_name, NEW.updated_by, NEW.updated_at, 'insert'); 
END; 

CREATE TRIGGER contacts_audit_update 
AFTER UPDATE 
    ON users FOR EACH ROW 
BEGIN 
    INSERT INTO contacts_audit (id, first_name, last_name, updated_by, updated_at, action) values (NEW.id, NEW.first_name, NEW.last_name, NEW.updated_by, NEW.updated_at, 'update'); 
END; 

CREATE TRIGGER contacts_audit_delete 
BEFORE DELETE 
    ON users FOR EACH ROW 
BEGIN 
    INSERT INTO contacts_audit (id, first_name, last_name, updated_by, updated_at, action) values (OLD.id, OLD.first_name, OLD.last_name, OLD.updated_by, OLD.updated_at, 'delete'); 
END; 

潛在的缺點

如果你正在使用一個MySQL的用戶名/密碼數據庫訪問和驗證用戶對MySQL中的users表,則在執行任何刪除之前,你將要進行更新,在PHP中,然後刪除,以便您可以捕獲誰刪除了您的記錄。

但是,如果你正在使用MySQL爲所有用戶的身份驗證,那麼你可以在你的觸發器有這樣的:以通知使用USER()

INSERT INTO contacts_audit (id, first_name, last_name, updated_by, updated_at, action) values (NEW.id, NEW.first_name, NEW.last_name, USER(), NEW.updated_at, 'insert'); 
+0

嗯,這就是我正在尋找的。所以你認爲這個解決方案比我上面發佈的泛型表「更好」? –

1
  1. 時間這兩種解決方案,你會看看哪一個更快ÿ OU。不可能知道哪些應用程序和環境會更快。
  2. 這是一個設計決定,所以它真的取決於你和你的要求。您有以下幾點需要考慮:

    • 如果用戶更改交易記錄,所有受影響的字段將被同一用戶同時更改。根據您的建議結構,所有這些更改都需要單獨輸入。

    • 由於您基本上必須重播插入記錄中的所有更改,因此更難以確定某個記錄在給定時間點與您提出的結構的相似程度。

    • 在專業方面,所有更改都存儲在一個表中,即使更改數據庫架構,也不必更改日誌記錄的結​​構。

    • 您還必須考慮是否要記錄所有表格的更改或僅選擇一些表格的更改。

    • 您還需要考慮如果記錄的表引用其他表,如何登錄。例如,如果您想記錄事務,那麼您可能有一個事務類型字段和一個單獨的事務類型表,其中列出了每個事務類型的詳細描述和其他信息。如果事務類型不再使用,那麼它可以從事務類型表中刪除,或者其參數可能會改變。

+0

Thanx對於這些因素,我會考慮並做出我的選擇 –