平时开发中常常须要记录时间,比方用于记录某条记录的创立工夫以及批改工夫。在数据库中存储工夫的形式有很多种,比方 MySQL 自身就提供了日期类型,比方 DATETIME,TIMESTAMEP 等,咱们也能够间接存储工夫戳为 INT 类型,也有人间接将工夫存储为字符串类型。
那么到底哪种存储工夫的形式更好呢?
不要应用字符串存储工夫类型
这是初学者很容易犯的谬误,容易间接将字段设置为 VARCHAR 类型,存储 ”2021-01-01 00:00:00″ 这样的字符串。当然这样做的长处是比较简单,上手快。
然而竭力不举荐这样做,因为这样做有两个比拟大的问题:
- 字符串占用的空间大
- 这样存储的字段比拟效率太低,只能一一字符比拟,无奈应用 MySQL 提供的日期 API
MySQL 中的日期类型
MySQL 数据库中常见的日期类型有 YEAR、DATE、TIME、DATETIME、TIMESTAMEP。因为个别都须要将日期准确到秒,其中比拟适合的有 DATETIME,TIMESTAMEP。
DATETIME
DATETIME 在数据库中存储的模式为:YYYY-MM-DD HH:MM:SS,固定占用 8 个字节。
从 MySQL 5.6 版本开始,DATETIME 类型反对毫秒,DATETIME(N) 中的 N 示意毫秒的精度。例如,DATETIME(6) 示意能够存储 6 位的毫秒值。
TIMESTAMEP
TIMESTAMP 理论存储的内容为‘1970-01-01 00:00:00’到当初的毫秒数。在 MySQL 中,因为类型 TIMESTAMP 占用 4 个字节,因而其存储的工夫下限只能到‘2038-01-19 03:14:07’。
从 MySQL 5.6 版本开始,类型 TIMESTAMP 也能反对毫秒。与 DATETIME 不同的是,若带有毫秒时,类型 TIMESTAMP 占用 7 个字节,而 DATETIME 无论是否存储毫秒信息,都占用 8 个字节。
类型 TIMESTAMP 最大的长处是能够带有时区属性,因为它实质上是从毫秒转化而来。如果你的业务须要对应不同的国家时区,那么类型 TIMESTAMP 是一种不错的抉择。比方新闻类的业务,通常用户想晓得这篇新闻公布时对应的本人国家工夫,那么 TIMESTAMP 是一种抉择。Timestamp 类型字段的值会随着服务器时区的变动而变动,主动换算成相应的工夫,说简略点就是在不同时区,查问到同一个条记录此字段的值会不一样。
TIMESTAMP 的性能问题
TIMESTAMP 还存在潜在的性能问题。
尽管从毫秒数转换到类型 TIMESTAMP 自身须要的 CPU 指令并不多,这并不会带来间接的性能问题。然而如果应用默认的操作系统时区,则每次通过时区计算工夫时,要调用操作系统底层零碎函数 __tz_convert(),而这个函数须要额定的加锁操作,以确保这时操作系统时区没有批改。所以,当大规模并发拜访时,因为热点资源竞争,会产生两个问题:
- 性能不如 DATETIME:DATETIME 不存在时区转化问题。
- 性能抖动:海量并发时,存在性能抖动问题。
为了优化 TIMESTAMP 的应用,倡议应用显式的时区,而不是操作系统时区。比方在配置文件中显示地设置时区,而不要应用零碎时区:
[mysqld]
time_zone = "+08:00"
简略总结一下这两种数据类型的优缺点:
- DATETIME 没有存储的工夫下限,而 TIMESTAMP 存储的工夫下限只能到‘2038-01-19 03:14:07’
- DATETIME 不带时区属性,须要前端或者服务端解决,然而仅从数据库保留数据和读取数据而言,性能更好
- TIMESTAMP 带有时区属性,然而每次须要通过时区计算工夫,并发拜访时会有性能问题
- 存储 DATETIME 比 TIMESTAMEP 多占用一部分空间
数值型工夫戳(INT)
很多时候,咱们也会应用 int 或者 bigint 类型的数值也就是工夫戳来示意工夫。
这种存储形式的具备 Timestamp 类型的所具备一些长处,并且应用它的进行日期排序以及比照等操作的效率会更高,跨零碎也很不便,毕竟只是寄存的数值。毛病也很显著,就是数据的可读性太差了,你无奈直观的看到具体工夫。
如果须要查看某个时间段内的数据
select * from t where created_at > UNIX_TIMESTAMP('2021-01-01 00:00:00');
DATETIME vs TIMESTAMP vs INT,怎么选?
每种形式都有各自的劣势,上面再对这三种形式做一个简略的比照:
TIMESTAMP 与 INT 实质一样,然而相比而言尽管 INT 对开发敌对,然而对 DBA 以及数据分析人员不敌对,可读性差。所以《高性能 MySQL》的作者举荐 TIMESTAMP 的起因就是它的数值示意工夫更加直观。上面是原文:
至于时区问题,能够由前端或者服务这里做一次转化,不肯定非要在数据库中解决。
总结
本文比拟了几种最常应用的存储工夫的形式,我最举荐的还是 DATETIME。理由如下:
- TIMESTAMP 比数值型工夫戳可读性更好
- DATETIME 的存储下限为 9999-12-31 23:59:59,如果应用 TIMESTAMP,则 2038 年须要思考解决方案
- DATETIME 因为不须要时区转换,所以性能比 TIMESTAMP 好
- 如果须要将工夫存储到毫秒,TIMESTAMP 要 7 个字节,和 DATETIME 8 字节差不太多
举荐浏览
技术选型:为什么批处理咱们却抉择了 Flink
Redis 存储对象信息是用 Hash 还是 String