面试题:能谈谈Date、Datetime、Time、Timestamp、year的区别吗?

一、 推荐阅读

首发地址:https://mp.weixin.qq.com/s/9zKX86P4kzlKla6-NyS3EA

使用推荐阅读,有更好的阅读体验

二、准备

如果面试官问你:了解 date、datetime、time、timestamp、year 有什么区别吗?

其实大概率就是看你曾经用过哪些,以及有没有留心对比它们的异同。如果你没有时间去做一下小实验,没关系!大概浏览一下我下面的小Case就OK了。

创建下面这张表,下面的 insert sql 都是往这个表中插入数据。

三、Year

支持范围:1901~2155 。

1901那年清政府签订了《辛丑条约》

在 MySQL5.7.5 中删除了对Year(2)的支持,同一转换为Year(4)。所以如果你使用这个版本的MySQL,会发现它会把年份以4位长度的数字展示给我们看。

你可以尝试插入一个超过它规定的上限2155的值 -- 2156 ,如下:

你会发现MySQL报错了,这是因为默认情况下MySQL开启了严格模式!

针对非法值的插入,MySQL是否报错取决于SQL是否开启了严格模式。

白日梦在上一篇“ 对NotNull字段插入Null值有什么现象” 中跟大家提及到了 什么是 sql mode,并且说了几个和日期相关的sql mode。不记得的同学可以去看一下。

比如通过下面的命令关闭严格模式。

然后插入非法值,结果很明显,不会报错。而且MySQL帮你插入了0值。

四、Date

支持的范围:1000-01-01 ~ 9999-12-31

下面做几个插入的小实验

看上面的例子,使用MySQL5.7默认的情况下是可以插入比1000-01-01更早的时间的!

那能不能插入0000-00-00呢?这取决于你使用的那种sql mode!

默认情况下是插入不进去的,如下:

插不进去的原因是:mysql5.7 默认的sql mode中开启了严格模式。

且开启使用了参数NO_ZERO_DATE

这个参数与严格模式一起起作用就会导致不能插入 0-0-0。

如果偏偏想插入 0-0-0 可以像下面这样将其去掉,然后重试。

五、Datetime

支持范围:1000-01-01 00:00:00.000000 to 9999-12-31 23:59:59.999999

很明显,Datetime比Date更精确。

不允许插入数字格式的日期。

六、Time

支持范围:-838:59:59.000000 to 838:59:59.000000

time类型不仅可以用来表示24h,还可以用来表示一个时间范围,这个时间范围可能会很大,甚至是负的。

下面做几个小实验

秒数是满60进1的。

所以我插入60时,在jdbc层面会爆出下面的错误:format exception


可以插入正常的时间

在看下面这个例子:

虽然mysql支持往time字中插入-838:59:59.000000 但是失败了。

原因如下图: IDE本身通过java的jdbc驱动连接MySQL。

jdbc尝试会将-838:59:59.000000 转换成Java的封装类,结果还转失败了。

在直接连接MySQL是不会出现上图这种情况的。

如果范围超过了 -838:59:59.000000 to 838:59:59.000000 这两个边界值 ,就插入这边界值。

接着再看几个典型的例子:

七、Timestamp

支持范围: 1970-01-01 00:00:01 UTC to 2038-01-19 03:14:07 UTC

因为32位能表示的最大值是2147483647。另外1年365天的总秒数是 31536000,2147483647/31536000 = 68.1,也就是说32位能表示的最长时间是68年,从1970年开始的话,加上68.1,实际最终到2038年01月19日03时14分07秒。

过了这个上线,所有32位操作系统时间都会变成10000000 00000000 00000000 00000000

这个问题在64位操作系统中已经不复存在

好,开始我们的实验!

先尝试插入几个零值,无一例外,全部报错失败。

再插入一些大点的值

你会不会诧异这样一个问题:

timestamp合法区间最小值不是1970-01-01 00:00:01吗?

那为什么在上面的例子中我尝试写入插入1970-01-01 00:00:01竟然会失败?

那是因为我机器上的MySQL使用的时区是CST:China Standard Time UT+8:00

以北京时间为准,我们是在东八区。所以最后是+8:00 , 而不是+0:00

所以如果我们在1970-0101-000001后顺延八个小时,就能插入成功!

补充:

列类型 显示格式
TIMESTAMP(14) YYYYMMDDHHMMSS
TIMESTAMP(12) YYMMDDHHMMSS
TIMESTAMP(10) YYMMDDHHMM
TIMESTAMP(8) YYYYMMDD
TIMESTAMP(6) YYMMDD
TIMESTAMP(4) YYMM
TIMESTAMP(2) YY

八、默认值

在你创建表的时候,可以为你的时间列选定一个默认值。



推荐阅读

  1. 大家常说的基数是什么?(已发布)
  2. 讲讲什么是慢查!如何监控?如何排查?(已发布)
  3. 对NotNull字段插入Null值有啥现象?(已发布)
  4. 能谈谈 date、datetime、time、timestamp、year的区别吗?(已发布)
  5. 了解数据库的查询缓存和BufferPool吗?谈谈看!(已发布)
  6. 你知道数据库缓冲池中的LRU-List吗?(已发布)
  7. 谈谈数据库缓冲池中的Free-List?(已发布)
  8. 谈谈数据库缓冲池中的Flush-List?(已发布)
  9. 了解脏页刷回磁盘的时机吗?(已发布)
  10. 用十一张图讲清楚,当你CRUD时BufferPool中发生了什么!以及BufferPool的优化!(已发布)
  11. 听说过表空间没?什么是表空间?什么是数据表?(已发布)
  12. 谈谈MySQL的:数据区、数据段、数据页、数据页究竟长什么样?了解数据页分裂吗?谈谈看!(已发布)
  13. 谈谈MySQL的行记录是什么?长啥样?(已发布)
  14. 了解MySQL的行溢出机制吗?(已发布)
  15. 说说fsync这个系统调用吧! (已发布)
  16. 简述undo log、truncate、以及undo log如何帮你回滚事物! (已发布)
  17. 我劝!这位年轻人不讲MVCC,耗子尾汁! (已发布)
  18. MySQL的崩溃恢复到底是怎么回事? (已发布)
  19. MySQL的binlog有啥用?谁写的?在哪里?怎么配置 (已发布)
  20. MySQL的bin log的写入机制 (已发布)


面试官都关注了!你还在犹豫什么呢?

posted @ 2020-11-13 09:51  赐我白日梦  阅读(996)  评论(2编辑  收藏  举报