I’m running MySQL 5.1.36 and have a database used for a web-based help desk system. The database has three tables I’d like to track changes for:
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;
Based on what I’ve read, the best way to handle this is to create duplicate tables, only with two extra fields per table:
ModifiedDateTime
Action
Is this really the best way? Every time even the slightest change is made to a record, the entire record is inserted into its corresponding history table. It seems like a huge waste of space. Is there a better way to do this?
It may or may not be a waste of space depends on typical operations with tables. For
INSERTandDELETEthe only way to track is to store all column values. Only forUPDATEyou can save some space. You can create 2 tables, for instance,and add records into these tables after each update. The problem here is that
old_valueandnew_valuecolumns should be large enough to keep value of any column from your original tables. So you probably need to create anotherupdate_history_details_text_blobsthat tracks only changes in text/blob columns.Update. Thus, the body of your after update trigger for
ticketstable may look like