在我们平时的开发中不可避免的要存储时间,比如我们需要在操作表中记录这个记录的时间,换乘的交易时间,发车时间等等。你会发现这个东西和我们这个时候的发展是息息相关的,用得好不好对我们的业务甚至功能都有很大的影响。所以我们有必要重新开始,好好了解这个东西。
这是一篇短小精悍的文章。仔细看可以学到很多东西!如果这篇文章有什么错误,请不嫌麻烦指出来。非常感谢!
1.切记不要用字符串存储日期
我记得在大学的时候是这么做的,现在很多不太懂数据库的新手也会这么做。显然,这种存储日期的方式还是有一些优点的,那就是简单明了,易于使用。
然而,这是不正确的,主要有两个问题:
字符串占用的空间更大!字符串存储的日期比较效率比较低(逐个字符进行比对),无法用日期相关的 API 进行计算和比较。2.Datetime 和 Timestamp 之间抉择
Datetime和Timestamp是MySQL提供的两种类似的数据类型。他们应该如何选择?
通常我们更喜欢时间戳。来说说为什么要这么做吧!
2.1 DateTime 类型没有时区信息的
DateTime类型没有时区信息(不考虑时区),DateTime类型保存的时间是当前会话设置的时区对应的时间。那么问题出在哪里?当您的时区改变时,例如更改您的服务器地址或更改客户端连接的时区设置,将导致您从数据库读取的时间错误。不要小看这个问题,很多系统都因为这个问题闹了很多笑话。
时间戳与时区相关。时间戳类型字段的值会随着服务器时区的变化而变化,并自动转换成相应的时间。简单来说,同一条记录在不同时区查询时,该字段的值会有所不同。
来实际演示一下吧!
表构建SQL语句:
CREATE TABLE ` time _ zone _ test `( ` id ` bigint(20)NOT NULL AUTO _ INCREMENT,` date_time` datetime DEFAULT NULL,` time _ stamp ` TIMESTAMP NOT NULL DEFAULT CURRENT _ TIMESTAMP ON UPDATE CURRENT _ TIMESTAMP,PRIMARY KEY(` id `))ENGINE = InnoDB DEFAULT CHARSET = utf8;插入数据:
插入time_zone_test(date_time,time_stamp)值(NOW()、NOW());查看数据:
select date_time,time _ stamp from time _ zone _ test结果:
+–+| date _ time | time _ stamp |+-+-+| 2020-01-11 09:53:32 | 2020-01-11 09:53:32 |+-+现在我们在跑。
修改当前会话的时区:
set time _ zone = & # 39+8:00';再次检查数据:
+–+| date _ time | time _ stamp |+-+-+| 2020-01-11 09:53:32 | 2020-01-11 17:53:32 |+-+扩展:关于MySQL的一些。
#查看当前会话时区SELECT @ @ session.time _ zone#设置当前会话时区SET time _ zone = & # 39欧洲/赫尔辛基& # 39;;SET time _ zone = & # 34+00:00";#数据库全局时区设置SELECT @ @ global.time _ zone#设置全球时区SET GLOBAL time _ zone = & # 39+8:00';设置全球时区= & # 39;欧洲/赫尔辛基& # 39;;2.2日期时间类型消耗空。Timestamp只需要4个字节的存储空,DateTime却需要8个字节的存储空。然而,这也产生了一个问题,Timestamp表示一个更小的时间范围。
DateTime :1000-01-01 00:00:00 ~ 9999-12-31 23:59:59Timestamp:1970-01-01 00:00:01 ~ 2037-12-31 23:59:59
\”
不同版本的MySQL中时间戳略有不同。
\”
3 再看 MySQL 日期类型存储空间
下图显示了MySQL版本中日期类型占用的存储空间空:
可以看出,5.6.4之后的MySQL多了一个小数位,需要0 ~ 3个字节。数据时间和时间戳将有几种不同的存储空占用率。
为了方便起见,我们仍然默认Timestamp只需要4个字节的存储空,但是DateTime需要8个字节的存储空。
4.数值型时间戳是更好的选择吗?
很多时候我们也会用int或者bigint类型的值,也就是timestamp来表示时间。
这种带有时间戳类型的存储方式有一些优点,对于日期的排序和比较会更高效,对于跨系统也很方便。毕竟它只是一个存储值。缺点也很明显,就是数据可读性太差,无法直观看到具体时间。
时间戳的定义如下:
\”
时间戳的定义来自一个参考时间,即“1970-1-1 00:00:00 +0:00”。从这个时候开始,用整数表示,以秒计算。随着时间的推移,这个时间整数不断增加。这样我只需要一个数值就可以完美的表示时间,而且这个数值是一个绝对的数值,也就是无论你在地球的哪个地方,这个表示时间的时间戳都是一样的,生成的数值也是一样的,而且没有时区的概念,所以在系统中时间的传递不需要额外的转换,只在显示给用户的时候,转换成字符串格式的当地时间。
\”
数据库中的实际操作:
mysql & gtselect UNIX _ TIMESTAMP(& # 39;2020-01-11 09:53:32');+-+| UNIX _ TIMESTAMP(& # 39;2020-01-11 09:53:32')|+ – +| 1578707612 |+ – +集合中1行(0.00秒)mysql & gtselect FROM _ UNIXTIME(1578707612);+-+| from _ UNIX time(1578707612)|+-。日期时间?时间戳?数值保存的时间戳?
似乎没有什么灵丹妙药。很多程序员会觉得数值时间戳真的很好,很高效,很兼容,但也有很多人觉得不够直观。对了,《高性能MySQL》作者推荐时间戳,因为时间的数值表示不够直观。以下为原文:
各有各的优势,根据实际场景来看才是王道。让我们对这三种方法进行简单的比较,以便您在实际开发中选择正确的存储时间数据类型:
如果你有任何问题,请给我留言!如果这篇文章有什么错误,请不嫌麻烦指出来。再次感谢!
在下面的文章中,我将介绍:Ja8对日期的支持以及为什么我们不能使用SimpleDateFormat。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。