This seems like a really simple one but I'm struggling to figure it out. I want a column in my database that lists when a record was first created and another column that says when it was updated. It's my understanding I should be able to do all this just using MySQL. All help is appreciated :)
This stinks still no answer, reasons I'm already starting to miss Ruby on Rails...
You will probably need to use a combination of the Datetime
datatype and the Timestamp
data type. I would set my created
column as a DateTime
with a DEFAULT NOW()
, and my updated
column as a Timestamp
with DEFAULT CURRENT_TIMESTAMP
and an ON UPDATE CURRENT_TIMESTAMP
attribute.
Here are the docs for the Timestamp
dt:
http://dev.mysql.com/doc/refman/5.0/en/timestamp.html
In a CREATE TABLE statement, the first TIMESTAMP column can be declared in any of the following ways:
With both DEFAULT CURRENT_TIMESTAMP and ON UPDATE CURRENT_TIMESTAMP clauses, the column has the current timestamp for its default value, and is automatically updated.
With neither DEFAULT nor ON UPDATE clauses, it is the same as DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP.
With a DEFAULT CURRENT_TIMESTAMP clause and no ON UPDATE clause, the column has the current timestamp for its default value but is not automatically updated.
With no DEFAULT clause and with an ON UPDATE CURRENT_TIMESTAMP clause, the column has a default of 0 and is automatically updated.
With a constant DEFAULT value, the column has the given default and is not automatically initialized to the current timestamp. If the column also has an ON UPDATE CURRENT_TIMESTAMP clause, it is automatically updated; otherwise, it has a constant default and is not automatically updated.
If you can't use the timestamp fields with default attributes that Paul W has suggested, you can use AFTER INSERT and AFTER UPDATE triggers to populate the fields.
You will need two fields "Created" and "Updated" with type datetime. When a new entry is inserted then insert "Created" with current time stamp. When a update is happening insert "Updated" with the current time stamp, and let the "Created" field remain as it is.
For current time stamp you can use NOW() in your mysql query.
To fulfill your question and for others viewing this question, here is the answer. Note this was written for MySQL 5.x.
DROP TABLE IF EXISTS `test1`;
CREATE TABLE `test1` (
`id` INT NULL AUTO_INCREMENT ,
`name` varchar(50) NOT NULL ,
`created` DATETIME ,
`updated` DATETIME ,
PRIMARY KEY (`id`),
INDEX (`name`)
);
DELIMITER $$
DROP TRIGGER IF EXISTS `test1_created`$$
CREATE TRIGGER `test1_created` BEFORE INSERT ON `test1`
FOR EACH ROW BEGIN
SET NEW.`created` = UTC_TIMESTAMP();
SET NEW.`updated` = UTC_TIMESTAMP();
END;
$$
DROP TRIGGER IF EXISTS `test1_updated`$$
CREATE TRIGGER `test1_updated` BEFORE UPDATE ON `test1`
FOR EACH ROW BEGIN
SET NEW.`updated` = UTC_TIMESTAMP();
END;
$$
DELIMITER ;
Note
You could use TIMESTAMP for the updated
column which would have automatically updated the value thus not requiring the BEFORE UPDATE trigger, however TIMESTAMP has a range from 1970 to 2038 which is fast approaching and I like to think my applications will live forever :). Although TIMESTAMP is only 4bytes while DATETIME is 8bytes.
TIMESTAMP range '1970-01-01 00:00:01' UTC to '2038-01-19 03:14:07' UTC
DATETIME range '1000-01-01 00:00:00' to '9999-12-31 23:59:59'
From the MySQL 5.0 Certification Guide:
CREATE TABLE ts_test5 (
created TIMESTAMP DEFAULT 0,
updated TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
data CHAR(30)
);
To control the initialization and update behaviour of a TIMESTAMP column, you add either or both of the DEFAULT CURRENT_TIMESTAMP and ON UPDATE CURRENT_TIMESTAMP attributes to the column defintion when creating the table with CREATE TABLE... and ...if you do not specify either of the DEFAULT CURRENT_TIMESTAMP or ON UPDATE CURRENT_TIMESTAMP attributes when creating a table, MySQL automatically assigns BOTH to the first TIMESTAMP column
Also
you cannot use DEFAULT CURRENT_TIMESTAMP with one column and ON UPDATE CURRENT_TIMESTAMP with another