2011-04-29 122 views
2

我正在運行MySQL 5.1.36並且有一個用於基於Web的幫助臺系統的數據庫。該數據庫有三個表我想跟蹤更改:跟蹤MySQL數據庫更改

CREATE TABLE IF NOT EXISTS `tickets` (
    `TicketNum` int(11) unsigned NOT NULL, 
    `SubmittedFromIP` tinyblob, 
    `SubmittedFromDevice` varchar(255) DEFAULT NULL, 
    `EntryDate` datetime DEFAULT NULL, 
    `ClosedDate` datetime DEFAULT NULL, 
    `LastName` varchar(50) DEFAULT NULL, 
    `FirstName` varchar(50) DEFAULT NULL, 
    `Email` varchar(50) DEFAULT NULL, 
    `Location` varchar(4) DEFAULT NULL, 
    `InventoryNumber` varchar(50) DEFAULT NULL, 
    `DeviceName` varchar(50) DEFAULT NULL, 
    `Description` text, 
    `Notes` text, 
    `Agent_ID` smallint(5) unsigned NOT NULL DEFAULT '1', 
    `TotalHoursSpent` float NOT NULL DEFAULT '0', 
    `Status` smallint(5) unsigned NOT NULL DEFAULT '1', 
    `Priority` tinyint(4) NOT NULL DEFAULT '0', 
    `LastUpdatedByAgent_ID` smallint(5) unsigned DEFAULT NULL, 
    PRIMARY KEY (`TicketNum`), 
    KEY `ClosedDate` (`ClosedDate`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

CREATE TABLE IF NOT EXISTS `ticketsolutions` (
    `Entry_ID` int(10) unsigned NOT NULL, 
    `TicketNum` mediumint(8) unsigned DEFAULT NULL, 
    `EntryDateTime` datetime DEFAULT NULL, 
    `HoursSpent` float DEFAULT NULL, 
    `Agent_ID` smallint(5) unsigned DEFAULT NULL, 
    `EntryText` text, 
    `LastUpdatedByAgent_ID` smallint(5) unsigned DEFAULT NULL, 
    PRIMARY KEY (`Entry_ID`), 
    KEY `TicketNum` (`TicketNum`), 
    KEY `EntryDateTime` (`EntryDateTime`), 
    KEY `HoursSpent` (`HoursSpent`), 
    KEY `Rating` (`Rating`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

CREATE TABLE IF NOT EXISTS `tickettagsmap` (
    `TicketNum` int(11) unsigned NOT NULL, 
    `Tag_ID` int(10) unsigned NOT NULL, 
    `AddedByAgent_ID` smallint(5) unsigned NOT NULL, 
    `DateTimeAdded` datetime NOT NULL, 
    PRIMARY KEY (`TicketNum`,`Tag_ID`), 
    KEY `Tag_ID` (`Tag_ID`), 
    KEY `fk_AgentID` (`AddedByAgent_ID`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

基於我讀過,來處理這個最好的方法是創建重複表格中,只有每桌兩個附加字段:

ModifiedDateTime 
Action 

這真的是最好的方法嗎?每當即使對記錄做出最輕微的改變,整個記錄都會被插入到相應的歷史記錄表中。這似乎是對空間的巨大浪費。有一個更好的方法嗎?

+1

**要看你的需求的最佳途徑,你想知道這些是什麼變化以及你想要什麼。 – Johan 2011-04-29 15:40:53

+0

我想知道什麼時候_anything_會隨着票證發生變化。例如,如果用戶提交的問題描述較差,則代理會更新描述以更好地描述問題。不過,我仍然想看看原始描述是什麼。我還想跟蹤票證的優先順序何時更改,何時將標籤添加到票證中,何時更改票證的狀態等。 – Paul 2011-04-29 15:49:57

+0

如果您想恢復某些內容以查看更改之前的狀態,則必須存儲您已知道如何執行的完整數據。 – Johan 2011-04-29 16:01:12

回答

4

它可能會或可能不會浪費空間取決於典型的表操作。對於INSERTDELETE,唯一的方法是存儲所有列值。只有UPDATE可以節省一些空間。您可以創建2個表格,例如,

update_history_main(id int not null auto_increment primary key, 
modify_date datetime not null, 
table_involved varchar(50) not null); 

update_history_details (id int not null auto_increment primary key, 
update_history_main_id int not null, 
field_name varchar(100), 
old_value varchar(100), 
new_value varchar(100), 
FOREIGN KEY (update_history_main_id) REFERENCES update_history_main(id) 
ON UPDATE CASCADE ON DELETE CASCADE); 

並在每次更新後向這些表中添加記錄。這裏的問題是old_valuenew_value列應該足夠大,以保留原始表中的任何列的值。因此,您可能需要創建另一個update_history_details_text_blobs,該文件僅跟蹤text/blob列中的更改。

更新。因此,對於tickets表您更新後觸發的身體可能看起來像

DELIMITER $$$ 
CREATE TRIGGER afterTicketUpdate AFTER UPDATE ON tickets 
FOR EACH ROW 
BEGIN 
    DECLARE main_id int; 
    INSERT INTO update_history_main(modify_date, table_involved) 
     VALUES(NOW(),'tickets'; 
    SELECT LAST_INSERT_ID() INTO main_id; 

    IF (new.SubmittedFromDevice != old.SubmittedFromDevice) THEN 
     INSERT INTO update_history_details(update_history_main_id, field_name, 
     old_value,new_value) 
    VALUES (main_id, 'SubmittedFromDevice',old.SubmittedFromDevice, 
     new.SubmittedFromDevice); 
    END IF; // ... check all other fields. 
END 
$$$ 
+1

+1建議將blob中的更改存儲在單獨的表中,並僅在更改時存儲這些更改。 – Johan 2011-04-29 16:02:06

+1

謝謝,這是一個不錯的主意。不過,我不知道這些查詢會如何查找。看起來它可能非常複雜。我將不得不玩弄它。 – Paul 2011-04-29 16:03:06

+0

我添加了一個可用於填充歷史數據的觸發器示例(原始草稿,您還需要在包含可空列的條件中處理NULL值) – a1ex07 2011-04-29 16:28:01

0

您可以爲每個表創建Triggers,以在插入,更新或刪除數據時運行。然後,您的跟蹤表格可能包含以下內容:

TicketNum   
ModifiedDateTime 
Action 

並且每次根據需要都更新觸發器。

0

一個簡單的方法做,這是

  1. 啓動MySQL記錄。
  2. 檢查日誌中的更新。

在MySQL中啓用日誌記錄:在MySQL後端控制檯

鍵入以下。

SET GLOBAL log_output = 'TABLE'; 
SET GLOBAL general_log = 'ON'; 

檢查更新與查詢:(可以自定義此您的需要)

select argument from mysql.general_log where argument REGEXP '*INSERT*';