前言:
我们在平时开发中不可避免的就是要存储时间,比如我们要记录操作表中每一条记录的时间,记录转账的交易时间、记录出发时间等等。这个东西与我们开发联系非常密切,用的好与不好会给我们的业务甚至功能带来很大的影响。

字符串存储日期

想必大家在刚开始接触开发的时候,这种做法是可取的,简单,容易上手,但是这种做法是有问题的:

  1. 字符串占用的空间更大
  2. 字符串存储的日期比较效率比较低(逐个字符进行比对),无法用用日期相关的API进行计算比较。

Datetime和Timestamp

Datetime 和 Timestamp 是 MySQL 提供的两种比较相似的保存时间的数据类型。他们两者究竟该如何选择呢?
首选TimeStamp。

  • DateTime类型没有时区信息的(时区无关)
    DateTime 类型保存的时间都是当前会话所设置的时区对应的时间。这样就会有什么问题呢?当你的时区更换之后,比如你的服务器更换地址或者更换客户端连接时区设置的话,就会导致你从数据库中读出的时间错误。不要小看这个问题,很多系统就是因为这个问题闹出了很多笑话。
  • Timestamp和时区有关
    Timestamp 类型字段的值会随着服务器时区的变化而变化,自动换算成相应的时间,说简单点就是在不同时区,查询到同一个条记录此字段的值会不一样。

测试一下:

CREATETABLE`time_zone_test` (
`id`bigint(20) NOTNULL AUTO_INCREMENT,
`date_time` datetime DEFAULTNULL,
`time_stamp` timestamp NOTNULLDEFAULTCURRENT_TIMESTAMPONUPDATECURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDBDEFAULTCHARSET=utf8;
INSERTINTO time_zone_test(date_time,time_stamp) VALUES(NOW(),NOW());
select date_time,time_stamp from time_zone_test;

结果:

[Mysql]  数据库如何存储时间_java


现在我们修改当前时区:

settime_zone='+8:00';

再次查看数据如下:

[Mysql]  数据库如何存储时间_java_02

在这里也列举一些Mysql时区设置的一个常用sql命令。

# 查看当前会话时区
SELECT @@session.time_zone;
# 设置当前会话时区
SETtime_zone = 'Europe/Helsinki';
SETtime_zone = "+00:00";
# 数据库全局时区设置
SELECT @@global.time_zone;
# 设置全局时区
SETGLOBALtime_zone = '+8:00';
SETGLOBALtime_zone = 'Europe/Helsinki';
  • DateTime 类型消耗空间更大
    Timestamp 只需要使用 4 个字节的存储空间,但是 DateTime 需要耗费 8 个字节的存储空间。但是,这样同样造成了一个问题,Timestamp 表示的时间范围更小。
  • DateTime :1000-01-01 00:00:00 ~ 9999-12-31 23:59:59
  • Timestamp:1970-01-01 00:00:01 ~ 2037-12-31 23:59:59
  • 数值型时间戳
    我们也可以使用int或者bigint类型的数值也就是时间戳来表示时间。

这种存储方式的具有 Timestamp 类型的所具有一些优点,并且使用它的进行日期排序以及对比等操作的效率会更高,跨系统也很方便,毕竟只是存放的数值。缺点也很明显,就是数据的可读性太差了,你无法直观的看到具体时间。
时间戳定义:
​​​时间戳的定义是从一个基准时间开始算起,这个基准时间是「1970-1-1 00:00:00 +0:00」,从这个时间开始,用整数表示,以秒计时,随着时间的流逝这个时间整数不断增加。这样一来,我只需要一个数值,就可以完美地表示时间了,而且这个数值是一个绝对数值,即无论的身处地球的任何角落,这个表示时间的时间戳,都是一样的,生成的数值都是一样的,并且没有时区的概念,所以在系统的中时间的传输中,都不需要进行额外的转换了,只有在显示给用户的时候,才转换为字符串格式的本地时间。​

在数据库中的操作:

mysql> select UNIX_TIMESTAMP('2020-01-11 09:53:32');
+---------------------------------------+
| UNIX_TIMESTAMP('2020-01-11 09:53:32') |
+---------------------------------------+
| 1578707612 |
+---------------------------------------+
1 row in set (0.00 sec)

mysql> select FROM_UNIXTIME(1578707612);
+---------------------------+
| FROM_UNIXTIME(1578707612) |
+---------------------------+
| 2020-01-11 09:53:32 |
+---------------------------+
1 row in set (0.01 sec)

总结

其实用哪个最好,没有正确答案的,但是还是推荐使用TimeStamp。因为时间戳表达的不够直观。这篇文章仅供参考,具体使用还是要具体场景具体分析的。没有绝对的答案!!!!!!!!实践是检验真理的唯一标准!!!!!!!!!!!!!!!!!!!!