# mysql用int做时间戳的问题

问题
项目中mysq数据库用int(11)来存储日期的时间戳格式,可在严格模式(Strict Mode)测试中发现在2038-01-19 11:14:07以后的日期无法存储,提示字段超出范围(Out of range value for column)。

分析
字段类型int,长度11,带符号型。
我们平时知道int的长度与存放的数值型的数的大小无关 ,也就是int(1)与int(11)存储的数值大小是一样的,所以关键要去查询int数值最大是多少。
INT类型的字节数是4,带符号时的范围是 -2147483648~2147483647,无符号时的范围是 0~4294967295。

结论
有符号的int类型最大值2147483647,转成日期为2038-01-19 11:14:07,如果想存储2038-01-19 11:14:07往后的日期可以:

  • 将字段改成unsigned,unsigned 是表示无符号数据类型,也就是非负数,因此对整数的表示范围扩大了1倍,无符号的int最大值为2106-02-07 14:28:15暂时可以满足需要
  • 将字段的类型更新为bigint
  • 存成Ymd的形式

附言
至于为什么用int作为日期时间的存储类型而不用datetime呢,int做时间戳有什么优缺点呢?

  • 优点:
    • int存储空间小,排序查询效率比datetime高。
    • 方便时间计算很好规避了时区问题。
    • 格式化在php,方便日期格式转换。
  • 缺点:
    • int日期范围有限制(0的时间戳转换为1970-01-01 08:00:00),可用bigint代替,而datetime支持的范围为'1000-01-01 00:00:00'到'9999-12-31 23:59:59'。
    • 可读性极差,无法直观的看到数据。