Showing posts with label Mysql Timestamp. Show all posts
Showing posts with label Mysql Timestamp. Show all posts

Tuesday, 30 July 2019

Mysql - What is the difference between UNIX TIMESTAMPS and MySQL TIMESTAMPS?

In MySQL, UNIX TIMESTAMPS are stored as 32-bit integers. On the other hand MySQL TIMESTAMPS are also stored in similar manner but represented in readable YYYY-MM-DD HH:MM:SS format.
Example:
mysql> Select UNIX_TIMESTAMP('2017-09-25 02:05:45') AS 'UNIXTIMESTAMP VALUE';
+---------------------+
| UNIXTIMESTAMP VALUE |
+---------------------+
| 1506285345          |
+---------------------+
1 row in set (0.00 sec)
The query above shows that UNIX TIMESTAMPS values are stored as 32 bit integers whose range is same as MySQL INTEGER data type range.
mysql> Select FROM_UNIXTIME(1506283345) AS 'MySQLTIMESTAMP VALUE';
+----------------------+
| MySQLTIMESTAMP VALUE |
+----------------------+
| 2017-09-25 01:32:25  |
+----------------------+
1 row in set (0.00 sec)
The query above shows that MySQL TIMESTAMPS values are also stored as 32 bit integers, but in a readable format, whose range is same as MySQL TIMESTAMP data type range.

Thursday, 8 November 2018

Mysql: When to use datetime or timestamp

 Answers


Assuming you're using MS SQL Server (Which you're not, see the Update below):
A table can have only one timestamp column. The value in the timestamp column is updated every time a row containing a timestamp column is inserted or updated. This property makes a timestamp column a poor candidate for keys, especially primary keys. Any update made to the row changes the timestamp value, thereby changing the key value. If the column is in a primary key, the old key value is no longer valid, and foreign keys referencing the old value are no longer valid. If the table is referenced in a dynamic cursor, all updates change the position of the rows in the cursor. If the column is in an index key, all updates to the data row also generate updates of the index.
Information on MSDN
If you need to store date/time information against a row, and not have that date/time change, use DateTime; otherwise, use Timestamp.
Also Note: MS SQL Server timestamp fields are not Dates nor Times, they are binary representations of the relative sequence of when the data was changed.

Update

As you've updated to say MySQL:
TIMESTAMP values are converted from the current time zone to UTC for storage, and converted back from UTC to the current time zone for retrieval. (This occurs only for the TIMESTAMP data type, not for other types such as DATETIME.)
Quote from MySQL Reference
More notably:
If you store a TIMESTAMP value, and then change the time zone and retrieve the value, the retrieved value is different from the value you stored.
So if you are using an application across timezones, and need the date/time to reflect individual users settings, use Timestamp. If you need consistency regardless of timezone, use Datetime






  • In MySQL, on DateTime type you can work with DATE() related functions, whereas on timestamp you can't.
  • Timestamp can not hold values before 01-01-1970.
  • Also, one of them holds the daylight savings and other don't (I don't remember which one right now)
I tend to always choose DateTime.

Mysql: Timestamps vs Datetime data types

I have a table (links) containing a column with dates (gdate). When I run the following statement I won't get any records at all, just the fields:

SELECT * FROM links WHERE gdate = 2000-11-05

N.B. The table do have a record with the above date and it doesn't work with another date either. The field type is dbtimestamp. Greetings from Sweden"
Ahhh. The dreaded TIMESTAMP datatype. Unfortunately you really can't use TIMESTAMP for any type of comparison. Or really for much of anything. To quote from SQL Server Books Online:

The SQL Server timestamp data type has nothing to do with times or dates. SQL Server timestamps are binary numbers that indicate the relative sequence in which data modifications took place in a database. The timestamp data type was originally implemented to support the SQL Server recovery algorithms.

It further states Never use timestamp columns in keys, especially primary keys, because the timestamp value changes every time the row is modified.

I'd suggest using a DATETIME or SMALLDATETIME column in this case. DATETIME columns can store dates from January 1st, 1753 through December 31st, 9999 (there's that Y10K problem) and are accurate to roughly 3 milliseconds. They use 8 bytes of storage. SMALLDATETIME columns can store dates from January 1st, 1900 through June 6th, 2079 and are accurate to the minute. SMALLDATETIME columns only use 4 bytes of storage.

You can insert values into DATETIME columns (or SMALLDATETIME) columns by enclosing them in quotes.

INSERT Table1 (DateTimeColumn)
VALUES ('6/3/2021')


This will insert the date part with the time set to midnight (12:00:00 AM). You can insert the current system date and time using the GETDATE() function:

INSERT Table1 (DateTimeColumn)
VALUES ( GETDATE() )


Your SELECT statement from above might look something like this:

SELECT * FROM links WHERE gdate = '2000-11-05'

This will run fine if you are putting dates in with no times. If you are adding times and want all the records for a particular day you can do something like this:

SELECT * FROM links WHERE LEFT( CONVERT(varchar, gdate, 120), 10) = '2000-11-05'

Using the CONVERT function makes SQL Server very picky about formats though (since that's what CONVERT does). I'd read up on CONVERT in Books Online. And greetings from America.

Wednesday, 31 October 2018

Should I use the datetime or timestamp data type in MySQL

Would you recommend using a datetime or a timestamp field, and why (using MySQL)?
I'm working with PHP on the server side.

 Answers


Timestamps in MySQL are generally used to track changes to records, and are often updated every time the record is changed. If you want to store a specific value you should use a datetime field.
If you meant that you want to decide between using a UNIX timestamp or a native MySQL datetime field, go with the native format. You can do calculations within MySQL that way ("SELECT DATE_ADD(my_datetime, INTERVAL 1 DAY)") and it is simple to change the format of the value to a UNIX timestamp ("SELECT UNIX_TIMESTAMP(my_datetime)") when you query the record if you want to operate on it with PHP.



I always use DATETIME fields for anything other than row metadata (date created or modified).
As mentioned in the MySQL documentation:
The DATETIME type is used when you need values that contain both date and time information. MySQL retrieves and displays DATETIME values in 'YYYY-MM-DD HH:MM:SS' format. The supported range is '1000-01-01 00:00:00' to '9999-12-31 23:59:59'.
...
The TIMESTAMP data type has a range of '1970-01-01 00:00:01' UTC to '2038-01-09 03:14:07' UTC. It has varying properties, depending on the MySQL version and the SQL mode the server is running in.
You're quite likely to hit the lower limit on TIMESTAMPs in general use -- e.g. storing birthdate.



The main difference is that DATETIME is constant while TIMESTAMP is affected by the time_zone setting.
So it only matters when you have — or may in the future have — synchronized clusters across time zones.
In simpler words: If I have a database in Australia, and take a dump of that database to synchronize/populate a database in America, then the TIMESTAMP would update to reflect the real time of the event in the new time zone, while DATETIME would still reflect the time of the event in the au time zone.
A great example of DATETIME being used where TIMESTAMP should have been used is in Facebook, where their servers are never quite sure what time stuff happened across time zones. Once I was having a conversation in which the time said I was replying to messages before the message was actually sent. (This, of course, could also have been caused by bad time zone translation in the messaging software if the times were being posted rather than synchronized.)






I recommend using neither a DATETIME or a TIMESTAMP field. If you want to represent a specific day as a whole (like a birthday), then use a DATE type, but if you're being more specific than that, you're probably interested in recording an actual moment as opposed to a unit of time (day,week,month,year). Instead of using a DATETIME or TIMESTAMP, use a BIGINT, and simply store the number of milliseconds since the epoch (System.currentTimeMillis() if you're using Java). This has several advantages:
  1. You avoid vendor lock-in. Pretty much every database supports integers in the relatively similar fashion. Suppose you want to move to another database. Do you want to worry about the differences between MySQL's DATETIME values and how Oracle defines them? Even among different versions of MySQL, TIMESTAMPS have a different level of precision. It was only just recently that MySQL supported milliseconds in the timestamps.
  2. No timezone issues. There's been some insightful comments on here on what happens with timezones with the different data types. But is this common knowledge, and will your co-workers all take the time to learn it? On the other hand, it's pretty hard to mess up changing a BigINT into a java.util.Date. Using a BIGINT causes a lot of issues with timezones to fall by the wayside.
  3. No worries about ranges or precision. You don't have to worry about what being cut short by future date ranges (TIMESTAMP only goes to 2038).
  4. Third-party tool integration. By using an integer, it's trivial for 3rd party tools (e.g. EclipseLink) to interface with the database. Not every third-party tool is going to have the same understanding of a "datetime" as MySQL does. Want to try and figure out in Hibernate whether you should use a java.sql.TimeStamp or java.util.Date object if you're using these custom data types? Using your base data types make's use with 3rd-party tools trivial.
This issue is closely related how you should store a money value (i.e. $1.99) in a database. Should you use a Decimal, or the database's Money type, or worst of all a Double? All 3 of these options are terrible, for many of the same reasons listed above. The solution is to store the value of money in cents using BIGINT, and then convert cents to dollars when you display the value to the user. The database's job is to store data, and NOT to intrepret that data. All these fancy data-types you see in databases(especially Oracle) add little, and start you down the road to vendor lock-in.



timestamp field is a special case of the datetime field. You can create timestamp columns to have special properties; it can be set to update itself on either create and/or update.
In "bigger" database terms, timestamp has a couple of special-case triggers on it.
What the right one is depends entirely on what you want to do.



2016 +: what I advise is to set your Mysql timezone to UTC and use DATETIME:

Any recent front-end framework (Angular 1/2, react, Vue,...) can easily and automatically convert your UTC datetime to local time.
Additionally:
(Unless you are likely to change the timezone of your servers)

Example with AngularJs
// back-end: format for angular within the sql query
SELECT DATE_FORMAT(my_datetime, "%Y-%m-%dT%TZ")...

// font-end Output the localised time
{{item.my_datetime | date :'medium' }}
All localised time format available here: https://docs.angularjs.org/api/ng/filter/date



I would always use a Unix timestamp when working with MySQL and PHP. The main reason for this being the the default date method in PHP uses a timestamp as the parameter, so there would be no parsing needed.
To get the current Unix timestamp in PHP, just do time();
and in MySQL do SELECT UNIX_TIMESTAMP();.



From my experiences, if you want a date field in which insertion happens only once and you don't want to have any update or any other action on that particular field, go with date time.
For example, consider a user table with a REGISTRATION DATE field. In that user table, if you want to know the last logged in time of a particular user, go with a field of timestamp type so that the field gets updated.
If you are creating the table from phpMyAdmin the default setting will update the timestamp field when a row update happens. If your timestamp filed is not updating with row update, you can use the following query to make a timestamp field get auto updated.
ALTER TABLE your_table
      MODIFY COLUMN ts_activity TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;



I always use a Unix timestamp, simply to maintain sanity when dealing with a lot of datetime information, especially when performing adjustments for timezones, adding/subtracting dates, and the like. When comparing timestamps, this excludes the complicating factors of timezone and allows you to spare resources in your server side processing (Whether it be application code or database queries) in that you make use of light weight arithmetic rather then heavier date-time add/subtract functions.
Another thing worth considering:
If you're building an application, you never know how your data might have to be used down the line. If you wind up having to, say, compare a bunch of records in your data set, with, say, a bunch of items from a third-party API, and say, put them in chronological order, you'll be happy to have Unix timestamps for your rows. Even if you decide to use MySQL timestamps, store a Unix timestamp as insurance.






I found unsurpassed usefulness in TIMESTAMP's ability to auto update itself based on the current time without the use of unnecessary triggers. That's just me though, although TIMESTAMP is UTC like it was said.
It can keep track across different timezones, so if you need to display a relative time for instance, UTC time is what you would want.



I prefer using timestamp so to keep everything in one common raw format and format the data in PHP code or in your SQL query. There are instances where it comes in handy in your code to keep everything in plain seconds.



TIMESTAMP requires 4 bytes, whereas a DATETIME requires 8 bytes.



A lot of answers here suggest to store as timestamp in the case you have to represent well defined points in time. But you can also have points in time with datetime if you store them all in UTC by convention.

MySQL DATETIME vs TIMESTAMP vs INT performance and benchmarking with MyISAM

Recently there was a discussion about DATETIME vs TIMESTAMP vs INT performance and storage requirements. If one setup was bound to disk usage, one would expect INT to perform better, since storage requirements are smaller. However, the amount of calculations to use it as a timestamp can be overwhelming as well.
So I went to do some benchmarks to see what we can conclude. The tests were run with:
  • MySQL 5.4.0-beta
  • Intel Quad core x 2800 MHz
  • Solaris 10
  • Single thread script to generate the data, and later on, simple LOAD DATA INFILEstatements (to be deterministic);
  • I should also note that for each test, the tables were recreated to be positively sure there was no caching at all (also, but not every iteration, I did a filesystem cache flush) and that the test itself was repeated a couple of times.
The schema used was basically this:

CREATE TABLE `test_datetime` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`datetime` FIELDTYPE NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM;

Being FIELDTYPE either DATETIME, TIMESTAMP and INT. As you may already have guessed, the INT timestamp will be UNIX style, by means of UNIX_TIMESTAMP() built-in function, which obviously adds some work to the server. However, remember there are calculations done for DATETIME and TIMESTAMP as well, since they are a kind of packed values.
The configuration file was pretty default, but for this test I don’t think there was much tweaking possible, since it’s all about INSERTs and table scans:

skip-locking
key_buffer = 128M
max_allowed_packet = 1M
table_cache = 512
sort_buffer_size = 2M
read_buffer_size = 2M
read_rnd_buffer_size = 8M
myisam_sort_buffer_size = 8M
thread_cache_size = 8
query_cache_type = 0
query_cache_size = 0
thread_concurrency = 4

For the initial generation of data, I wrote a small script to load sequentially 10.000.000 rows of timestamped data. The results were:
           avg          min          max       Data_length
DATETIME   14111 14010        14369     130000000
TIMESTAMP  13888        13887        14122     90000000
INT        13270        12970        13496     90000000

We can see that DATETIME performs better and indeed the INT time was the slower one. So far, it seems that the time conversion function has a notable impact, considering the same I/O is done for TIMESTAMP. That’s why I did another test: I dumped the data using SELECT … INTO OUTFILE so the same converted that was available:

mysql> select * from test_datetime into outfile ‘/tmp/test_datetime.sql’;
Query OK, 10000000 rows affected (6.19 sec)


mysql> select * from test_timestamp into outfile ‘/tmp/test_timestamp.sql’;
Query OK, 10000000 rows affected (8.75 sec)


mysql> select * from test_int into outfile ‘/tmp/test_int.sql’;
Query OK, 10000000 rows affected (4.29 sec)

Interesting how things turned: we now eliminated the calculations done for INT, but since the DATETIME and TIMESTAMP fields are exported as usual strings, they have to be reconverted for every row. By reading the calculations done for both types it’s easier to understand that the former was stored more packed than the latter.
I did more testing. In order to use the same data for the queries below, which will be mostly READ, I did a quick transformation to the data:

alter table test_datetime rename test_int;
alter table test_int add column datetimeint INT NOT NULL;
update test_int set datetimeint = UNIX_TIMESTAMP(datetime);
alter table test_int drop column datetime;
alter table test_int change column datetimeint datetime int not null;
select * from test_int into outfile ‘/tmp/test_int2.sql’;
drop table test_int;

So now I have exactly the same timestamps from the DATETIME test, and it will be possible to reuse the originals for TIMESTAMP tests as well.

mysql> load data infile ‘/export/home/ntavares/test_datetime.sql’ into table test_datetime;
Query OK, 10000000 rows affected (41.52 sec)
Records: 10000000 Deleted: 0 Skipped: 0 Warnings: 0


mysql> load data infile ‘/export/home/ntavares/test_datetime.sql’ into table test_timestamp;
Query OK, 10000000 rows affected, 44 warnings (48.32 sec)
Records: 10000000 Deleted: 0 Skipped: 0 Warnings: 44


mysql> load data infile ‘/export/home/ntavares/test_int2.sql’ into table test_int;
Query OK, 10000000 rows affected (37.73 sec)
Records: 10000000 Deleted: 0 Skipped: 0 Warnings: 0

As expected, since INT is simply stored as is while the others have to be recalculated. Notice how TIMESTAMP still performs worse, even though uses half of DATETIME storage size.
Let’s check the performance of full table scan:

mysql> SELECT SQL_NO_CACHE count(id) FROM test_datetime WHERE datetime > ‘1970-01-01 01:30:00′ AND datetime < ‘1970-01-01 01:35:00′;
+———–+
| count(id) |
+———–+
|    211991 |
+———–+
1 row in set (3.93 sec)


mysql> SELECT SQL_NO_CACHE count(id) FROM test_timestamp WHERE datetime > ‘1970-01-01 01:30:00′ AND datetime < ‘1970-01-01 01:35:00′;
+———–+
| count(id) |
+———–+
|   211991 |
+———–+
1 row in set (9.87 sec)


mysql> SELECT SQL_NO_CACHE count(id) FROM test_int WHERE datetime > UNIX_TIMESTAMP(’1970-01-01 01:30:00′) AND datetime < UNIX_TIMESTAMP(’1970-01-01 01:35:00′);
+———–+
| count(id) |
+———–+
|    211991 |
+———–+
1 row in set (15.12 sec)

Then again, TIMESTAMP performs worse and the recalculations seemed to impact, so the next good thing to test seemed to be without those recalculations: find the equivalents of those UNIX_TIMESTAMP() values, and use them instead:

mysql> select UNIX_TIMESTAMP(’1970-01-01 01:30:00′) AS lower, UNIX_TIMESTAMP(’1970-01-01 01:35:00′) AS bigger;
+——-+——–+
| lower | bigger |
+——-+——–+
|  1800 |   2100 |
+——-+——–+
1 row in set (0.00 sec)


mysql> SELECT SQL_NO_CACHE count(id) FROM test_int WHERE datetime > 1800 AND datetime < 2100;
+———–+
| count(id) |
+———–+
|    211991 |
+———–+
1 row in set (1.94 sec)


It’s very important to note that before the last SELECT I forced a filesystem cache flush. But finally, INT shows a huge difference - in fact, the expectable half times, probably due to the storage size (half of DATETIME). I’ve tried to benchmark UNIX_TIMESTAMP() alone, but could not come up with any conclusion:

mysql> select benchmark(10000000,UNIX_TIMESTAMP(’1970-01-01 01:35:00′))
+————————————————————+
| benchmark(100000000,UNIX_TIMESTAMP(’1970-01-01 01:35:00′)) |
+————————————————————+
|                                                          0 |
+————————————————————+
1 row in set (1 min 7.02 sec)

And this result is indeed weird, meaning that the function is not called twice for each row..?
Regarding TIMESTAMP vs DATETIME, I see only problems with the former: it’s limited to dates bigger than year 1970 (like INT, except that you can use the latter with your own time-offset), it’s slower in every aspect, and remeber that ‘0′ in a TIMESTAMP means ‘0000-00-00 00:00:00‘ and not ‘1970-01-01 00:00:01‘. According to a a related test by DBTuna team comparing both data type’s range scans, TIMESTAMP renders 55% slower, so I start to question this data type existence…
Anyway, what I’ve tried to demonstrate was usage scenarios that you’ll need to consider for your own real cases: INT remain smaller in storage (50%) and will only perform better if INSERTs and SELECTs are already fed with an INT value - and this is specially relevant for WRITE-intensive scenarios - but DATETIME alleviates extra responsability/care from the developer. Programmers don’t usually care about this, and want the most flexibility from the database, so it’s up to you to find with them a compromise. I may have provided both enough arguments for an endless discussion, though

Wednesday, 24 October 2018

MySQL: Datetime Versus Timestamp Data Types

The temporal data types in MySQL can be confusing. Hopefully, this example and discussion will help to explain the differences in the timestamp and datetime data types.
The DATETIME type is used for values that contain both date and time parts. MySQL retrieves and displays DATETIME values in ‘YYYY-MM-DD HH:MM:SS’ format. The supported range is ‘1000-01-01 00:00:00’ to ‘9999-12-31 23:59:59’.
The TIMESTAMP data type is used for values that contain both date and time parts. TIMESTAMP has a range of ‘1970-01-01 00:00:01’ UTC to ‘2038-01-19 03:14:07’ UTC.
A major difference between these two data types is that TIMESTAMP data type values are converted from current time zone to UTC for storage purpose and converted back from UTC to current time zone when used. The datetime data type values are unchanged in relation to time zone.
This example is a good exercise in demonstrating the difference between these two data types.
mysql> show variables like '%time_zone%';
+------------------+---------------------+
| Variable_name    |  Value              |
+------------------+---------------------+
| system_time_zone | India Standard Time |
| time_zone        | Asia/Calcutta       |
+------------------+---------------------+
2 rows in set (0.00 sec)

You can see our current time zone information. Under this environment, let us create a table with the two data types and populate it with the same temporal information.
create table datedemo
(
 mydatetime datetime,
 mytimestamp timestamp
);

Query OK, 0 rows affected (0.05 sec)
insert into datedemo values ((now()), (now()));

Query OK, 1 row affected (0.02 sec)
select * from datedemo;
+---------------------+---------------------+
| mydatetime          | mytimestamp         |
+---------------------+---------------------+
| 2011-08-21 14:11:09 | 2011-08-21 14:11:09 |
+---------------------+---------------------+
1 row in set (0.00 sec)

At this point the datetime and timestamp data types have remained the exact same values. Let us change the time zone see the results.
SET TIME_ZONE = "america/new_york";

Query OK, 0 rows affected (0.00 sec)
 select * from datedemo;
+---------------------+---------------------+
| mydatetime          | mytimestamp         |
+---------------------+---------------------+
| 2011-08-21 14:11:09 | 2011-08-21 04:41:09 |
+---------------------+---------------------+
1 row in set (0.00 sec)

The above example shows how the TIMESTAMP date type changed the values after changing the time-zone to ‘america/new_work’ where DATETIME is unchanged.

Monday, 8 October 2018

Should I use the datetime or timestamp data type in MySQ

Timestamps in MySQL are generally used to track changes to records, and are often updated every time the record is changed. If you want to store a specific value you should use a datetime field.
If you meant that you want to decide between using a UNIX timestamp or a native MySQL datetime field, go with the native format. You can do calculations within MySQL that way ("SELECT DATE_ADD(my_datetime, INTERVAL 1 DAY)") and it is simple to change the format of the value to a UNIX timestamp ("SELECT UNIX_TIMESTAMP(my_datetime)") when you query the record if you want to operate on it with PHP.



I always use DATETIME fields for anything other than row metadata (date created or modified).
As mentioned in the MySQL documentation:
The DATETIME type is used when you need values that contain both date and time information. MySQL retrieves and displays DATETIME values in 'YYYY-MM-DD HH:MM:SS' format. The supported range is '1000-01-01 00:00:00' to '9999-12-31 23:59:59'.
...
The TIMESTAMP data type has a range of '1970-01-01 00:00:01' UTC to '2038-01-09 03:14:07' UTC. It has varying properties, depending on the MySQL version and the SQL mode the server is running in.
You're quite likely to hit the lower limit on TIMESTAMPs in general use -- e.g. storing birthdate.



The main difference is that DATETIME is constant while TIMESTAMP is affected by the time_zone setting.
So it only matters when you have — or may in the future have — synchronized clusters across time zones.
In simpler words: If I have a database in Australia, and take a dump of that database to synchronize/populate a database in America, then the TIMESTAMP would update to reflect the real time of the event in the new time zone, while DATETIME would still reflect the time of the event in the au time zone.
A great example of DATETIME being used where TIMESTAMP should have been used is in Facebook, where their servers are never quite sure what time stuff happened across time zones. Once I was having a conversation in which the time said I was replying to messages before the message was actually sent. (This, of course, could also have been caused by bad time zone translation in the messaging software if the times were being posted rather than synchronized.)






I recommend using neither a DATETIME or a TIMESTAMP field. If you want to represent a specific day as a whole (like a birthday), then use a DATE type, but if you're being more specific than that, you're probably interested in recording an actual moment as opposed to a unit of time (day,week,month,year). Instead of using a DATETIME or TIMESTAMP, use a BIGINT, and simply store the number of milliseconds since the epoch (System.currentTimeMillis() if you're using Java). This has several advantages:
  1. You avoid vendor lock-in. Pretty much every database supports integers in the relatively similar fashion. Suppose you want to move to another database. Do you want to worry about the differences between MySQL's DATETIME values and how Oracle defines them? Even among different versions of MySQL, TIMESTAMPS have a different level of precision. It was only just recently that MySQL supported milliseconds in the timestamps.
  2. No timezone issues. There's been some insightful comments on here on what happens with timezones with the different data types. But is this common knowledge, and will your co-workers all take the time to learn it? On the other hand, it's pretty hard to mess up changing a BigINT into a java.util.Date. Using a BIGINT causes a lot of issues with timezones to fall by the wayside.
  3. No worries about ranges or precision. You don't have to worry about what being cut short by future date ranges (TIMESTAMP only goes to 2038).
  4. Third-party tool integration. By using an integer, it's trivial for 3rd party tools (e.g. EclipseLink) to interface with the database. Not every third-party tool is going to have the same understanding of a "datetime" as MySQL does. Want to try and figure out in Hibernate whether you should use a java.sql.TimeStamp or java.util.Date object if you're using these custom data types? Using your base data types make's use with 3rd-party tools trivial.
This issue is closely related how you should store a money value (i.e. $1.99) in a database. Should you use a Decimal, or the database's Money type, or worst of all a Double? All 3 of these options are terrible, for many of the same reasons listed above. The solution is to store the value of money in cents using BIGINT, and then convert cents to dollars when you display the value to the user. The database's job is to store data, and NOT to intrepret that data. All these fancy data-types you see in databases(especially Oracle) add little, and start you down the road to vendor lock-in.



timestamp field is a special case of the datetime field. You can create timestamp columns to have special properties; it can be set to update itself on either create and/or update.
In "bigger" database terms, timestamp has a couple of special-case triggers on it.
What the right one is depends entirely on what you want to do.



2016 +: what I advise is to set your Mysql timezone to UTC and use DATETIME:

Any recent front-end framework (Angular 1/2, react, Vue,...) can easily and automatically convert your UTC datetime to local time.
Additionally:
(Unless you are likely to change the timezone of your servers)

Example with AngularJs
// back-end: format for angular within the sql query
SELECT DATE_FORMAT(my_datetime, "%Y-%m-%dT%TZ")...

// font-end Output the localised time
{{item.my_datetime | date :'medium' }}
All localised time format available here: https://docs.angularjs.org/api/ng/filter/date



I would always use a Unix timestamp when working with MySQL and PHP. The main reason for this being the the default date method in PHP uses a timestamp as the parameter, so there would be no parsing needed.
To get the current Unix timestamp in PHP, just do time();
and in MySQL do SELECT UNIX_TIMESTAMP();.



From my experiences, if you want a date field in which insertion happens only once and you don't want to have any update or any other action on that particular field, go with date time.
For example, consider a user table with a REGISTRATION DATE field. In that user table, if you want to know the last logged in time of a particular user, go with a field of timestamp type so that the field gets updated.
If you are creating the table from phpMyAdmin the default setting will update the timestamp field when a row update happens. If your timestamp filed is not updating with row update, you can use the following query to make a timestamp field get auto updated.
ALTER TABLE your_table
      MODIFY COLUMN ts_activity TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;



I always use a Unix timestamp, simply to maintain sanity when dealing with a lot of datetime information, especially when performing adjustments for timezones, adding/subtracting dates, and the like. When comparing timestamps, this excludes the complicating factors of timezone and allows you to spare resources in your server side processing (Whether it be application code or database queries) in that you make use of light weight arithmetic rather then heavier date-time add/subtract functions.
Another thing worth considering:
If you're building an application, you never know how your data might have to be used down the line. If you wind up having to, say, compare a bunch of records in your data set, with, say, a bunch of items from a third-party API, and say, put them in chronological order, you'll be happy to have Unix timestamps for your rows. Even if you decide to use MySQL timestamps, store a Unix timestamp as insurance.






I found unsurpassed usefulness in TIMESTAMP's ability to auto update itself based on the current time without the use of unnecessary triggers. That's just me though, although TIMESTAMP is UTC like it was said.
It can keep track across different timezones, so if you need to display a relative time for instance, UTC time is what you would want.



I prefer using timestamp so to keep everything in one common raw format and format the data in PHP code or in your SQL query. There are instances where it comes in handy in your code to keep everything in plain seconds.



TIMESTAMP requires 4 bytes, whereas a DATETIME requires 8 bytes.



A lot of answers here suggest to store as timestamp in the case you have to represent well defined points in time. But you can also have points in time with datetime if you store them all in UTC by convention.