Whether to use or not to use: DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP In one Database table, created_at &amp; updated_at are defined as:

`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT 'Updated At',


And in another database table, it's defined as:

`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT 'Created At',
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT 'Updated At',


created_at -> stores datetime when the data is created.
updated_at -> stores the datetime when data is updated.

Which definition among above two would you prefer &amp; why?
Tested on 5.5.34

I looked at this in detail (I'm interested for an upcoming project, and it's been a while since I've "got my hands dirty"...)

It appears that datetimes are hard to set defaults for - see here. From what I've read, things have got better in 5.6 - I'll see if I have time to test tomorrow.

I think that your best solution is as below. The answer to your question about the best way to CREATE your TABLE is shown (IMHO). It involves inversing the ON UPDATE clause, putting it (logically enough) with the updated_at field.

mysql&gt; CREATE TABLE mt8
    -&gt; (
    -&gt;   billy int,
    -&gt;   created_at timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT 'Created At',
    -&gt;   updated_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'Created At'
    -&gt; );
Query OK, 0 rows affected (0.16 sec)

mysql&gt; 
mysql&gt; 
mysql&gt; DELIMITER $$
mysql&gt; create trigger my_ins8_trigger
    -&gt; before insert on mt8
    -&gt; for each row
    -&gt; begin
    -&gt;   set new.created_at = current_timestamp;
    -&gt; end $$
Query OK, 0 rows affected (0.08 sec)

mysql&gt; DELIMITER ;
mysql&gt; 
mysql&gt; 
mysql&gt; insert into mt8 values(123, null, null);
Query OK, 1 row affected (0.08 sec)

mysql&gt; insert into mt8 values(454, null, null);
Query OK, 1 row affected (0.05 sec)

mysql&gt; insert into mt8 values(1676, null, null);
Query OK, 1 row affected (0.06 sec)

mysql&gt; insert into mt8 (billy) values(34334);
Query OK, 1 row affected (0.07 sec)

mysql&gt; insert into mt8 (billy) values(3506);
Query OK, 1 row affected (0.05 sec)

mysql&gt; insert into mt8 (billy) values(3435454);
Query OK, 1 row affected (0.05 sec)

mysql&gt; select * from mt8;
+---------+---------------------+---------------------+
| billy   | created_at          | updated_at          |
+---------+---------------------+---------------------+
|     123 | 2014-06-12 01:53:40 | 2014-06-12 01:53:40 |
|     454 | 2014-06-12 01:53:40 | 2014-06-12 01:53:40 |
|    1676 | 2014-06-12 01:53:40 | 2014-06-12 01:53:40 |
|   34334 | 2014-06-12 01:53:56 | 2014-06-12 01:53:56 |
|    3506 | 2014-06-12 01:53:56 | 2014-06-12 01:53:56 |
| 3435454 | 2014-06-12 01:53:56 | 2014-06-12 01:53:56 |
+---------+---------------------+---------------------+
6 rows in set (0.00 sec)

mysql&gt; update mt8 set billy = 455 where billy = 454;
Query OK, 1 row affected (0.06 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql&gt; select * from mt8;
+---------+---------------------+---------------------+
| billy   | created_at          | updated_at          |
+---------+---------------------+---------------------+
|     123 | 2014-06-12 01:53:40 | 2014-06-12 01:53:40 |
|     455 | 2014-06-12 01:53:40 | 2014-06-12 01:54:26 |
|    1676 | 2014-06-12 01:53:40 | 2014-06-12 01:53:40 |
|   34334 | 2014-06-12 01:53:56 | 2014-06-12 01:53:56 |
|    3506 | 2014-06-12 01:53:56 | 2014-06-12 01:53:56 |
| 3435454 | 2014-06-12 01:53:56 | 2014-06-12 01:53:56 |
+---------+---------------------+---------------------+
6 rows in set (0.00 sec)
mysql&gt;


For the row with billy = 455, the update timestamp has changed, but not the created one - exactly as you'd want!