I'm currently doing a history table that basically logs every single modification in a history table, and adding the Action executed.
CREATE TABLE `competencies` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(255) NOT NULL,
`type` varchar(255) NOT NULL,
`credit_hour_equivalent` double NOT NULL,
`description` text,
`book_name` varchar(255) DEFAULT NULL,
`domain_id` int(11) DEFAULT NULL,
`created_at` datetime DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
`slug` varchar(255) DEFAULT NULL,
`video_id` int(11) DEFAULT NULL,
`statement_id` int(11) DEFAULT NULL,
`author_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `slug` (`slug`),
KEY `competencies_domain_id_index` (`domain_id`)
) ENGINE=InnoDB AUTO_INCREMENT=162 DEFAULT CHARSET=utf8;
CREATE TABLE `history_competencies` (
`id` int(11) DEFAULT NULL,
`title` varchar(255) DEFAULT NULL,
`type` varchar(255) DEFAULT NULL,
`credit_hour_equivalent` double DEFAULT NULL,
`description` text,
`book_name` varchar(255) DEFAULT NULL,
`domain_id` int(11) DEFAULT NULL,
`created_at` datetime DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
`slug` varchar(255) DEFAULT NULL,
`video_id` int(11) DEFAULT NULL,
`statement_id` int(11) DEFAULT NULL,
`author_id` int(11) DEFAULT NULL,
`author_action` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
For every INSERT
on competencies
I want to copy the row into history_competencies
.
So I created the following trigger
CREATE TRIGGER `after_insert_log_competency` after INSERT
ON `competencies`
FOR EACH row
INSERT INTO history_competencies
VALUES (NEW.`id`,
NEW.`title`,
NEW.`type`,
NEW.`credit_hour_equivalent`,
NEW.`description`,
NEW.`book_name`,
NEW.`domain_id`,
NEW.`created_at`,
NEW.`updated_at`,
NEW.`slug`,
NEW.`video_id`,
NEW.`statement_id`,
NEW.`author_id`,
'CREATE');
My question aims to find a better way to write the trigger so I don't have to DROP and CREATE the trigger every time that I change the competencies
table or reuse for other tables just changing the table names.
I was looking for something like
CREATE TRIGGER `after_insert_log_competency` after INSERT
ON `competencies`
FOR EACH row
INSERT INTO history_competencies
VALUES (NEW.*, 'CREATE');
Or
CREATE TRIGGER `after_insert_log_competency` after INSERT
ON `competencies`
FOR EACH row
INSERT INTO history_competencies
VALUES (NEW, 'CREATE');
But it didn't work.
Do you know if this is even possible?
Thank you!
Best Answer
One idea would be to write:
That doesn't work well for deletions, as the row wouldn't exist anymore. Also, you are doing an extra
eq_ref
for each write.But be careful, because if you ALTER competencies without altering history_competencies, all your INSERTS, etc. on competencies will fail due to the trigger failing.
If you do very frequently ALTERs, and all you do is inserting and selecting those new fields, you could serialize them to a single BLOB. That is a very denormal form, with a lot of drawbacks (no constraints, no indexes, difficult to update a single field), but it may be interesting in some cases.