Mysql - 如何决定用 datetime、timestamp、int 哪种类型存储时间戳?

简介: Mysql - 如何决定用 datetime、timestamp、int 哪种类型存储时间戳?

背景


  • 数据表都很可能会有一两个字段需要保存日期时间数据,那应该用什么 Mysql 类型来保存呢?
  • 前面讲过 datetime、timestamp、int 的方式来保存日期时间

如何存储 10位、13位的 unix 时间戳?

date、datetime、timestamp 的区别

本篇文章会对 datetime、timestamp、int 进行比较,然后对一些典型的查询进行基准测试,来决定什么情况下使用哪种数据类型

 

整体对比表


加粗是缺点

Feature

datetime

timestamp

Int (存储 Unix time)

本地时间表示

Yes

Yes

No,如果要表示为本地时间需要借助转换函数,比如FROM_UNIXTIME()

存储小数秒

Yes,高达 6 位精度

Yes,高达 6 位精度

No

有效范围

'1000-01-01 00:00:00.000000'
to
'9999-12-31 23:59:59.999999

'1970-01-01 00:00:01.000000'
to
'2038-01-19 03:14:07.999999'

如果是无符号,
'1970-01-01 00:00:01.000000;
理论上可到
'2106-2-07 06:28:15'

自动初始化 (MySQL 5.6.5+)

Yes

Yes

No

可读性好

Yes

Yes

No, 必须转换才能知道具体时间点

存储时间值会转换为 UTC 时间

No

Yes

No

可以改成其他了诶性

Yes,

如果结果值在有效时间范围内

Yes

Yes, 如果结果值在有效时间范围内并使用了转换函数

存储要求

(MySQL 5.6.4+)

5 bytes(加上最多 3 个字节的小数秒,如果使用)

4 bytes(加上最多 3 个字节的小数秒,如果使用)

4 bytes (no fractional seconds allowed)

 

接下来对 int、timestamp、datetime 的性能进行基准测试


  • 这里直接展示结果,不展示过程了(因为只需要关注结果即可)
  • 感兴趣可以看:https://vertabelo.com/blog/
  • 这里会使用 sysbench、mysqlslap 两个性能测试工具

 

测试一:选择日期范围内的值


下列查询均是从 1,497,421 个可用数据中返回 75,706 行

datetime

SELECT SQL_NO_CACHE
    measured_on
FROM
    vertabelo.datetimemeasures m
WHERE
    m.measured_on > '2016-01-01 00:00:00.0'
        AND m.measured_on < '2016-02-01 00:00:00.0';


Response time (ms) Sysbench mysqlslap
Min 152 296
Max 1261 3203
Average 362 809

 

timestamp

SELECT SQL_NO_CACHE
    measured_on
FROM
    vertabelo.timestampmeasures m
WHERE
    m.measured_on > '2016-01-01 00:00:00.0'
        AND m.measured_on < '2016-02-01 00:00:00.0'; 


Response time (ms) Sysbench mysqlslap
Min 214 359
Max 1389 3313
Average 431 1004

 

int(使用 FROM_UNIXTIME 转换函数)

SELECT SQL_NO_CACHE
    measured_on
FROM
    vertabelo.inttimestampmeasures m
WHERE
    FROM_UNIXTIME(m.measured_on) > '2016-01-01 00:00:00.0'
        AND FROM_UNIXTIME(m.measured_on) < '2016-02-01 00:00:00.0';


Response time (ms) Sysbench mysqlslap
Min 2472 7968
Max 6554 10312
Average 4107 8527

 

int

SELECT SQL_NO_CACHE
    measured_on
FROM
    vertabelo.inttimestampmeasures m
WHERE
    m.measured_on > 1451617200
        AND m.measured_on < 1454295600;


Response time (ms) Sysbench mysqlslap
Min 88 171
Max 275 2157
Average 165 514

 

结论

  • 两个基准测试工具都表明 datime 比 timestamp 和 int(使用转换函数) 快
  • 但是 datetime 并不比直接用 int 数字快
Avg response time (ms) Sysbench 相对于 datetime 的速度 mysqlslap 相对于 datetime 的速度
datetime 362 - 809 -
timestamp 431 19% slower 1004 24% slower
int(使用转换函数) 4107 1134% slower 8527 1054% slower
int 165 55% faster 514 36% faster

 

测试二:选择星期一的数据


下列查询均是从 1,497,421 个可用数据中返回 221,850 行

datetime

SELECT SQL_NO_CACHE measured_on
FROM
    vertabelo.datetimemeasures m
WHERE
    WEEKDAY(m.measured_on) = 0 #MONDAY;
Response time (ms) Sysbench mysqlslap
Min 1874 4343
Max 6168 7797
Average 3127 6103

 

timestamp

SELECT SQL_NO_CACHE
    measured_on
FROM
    vertabelo.timestampmeasures m
WHERE
    WEEKDAY(m.measured_on) = 0 #MONDAY;
Response time (ms) Sysbench mysqlslap
Min 2688 5953
Max 6666 13531
Average 3653 8412

 

int(使用 FROM_UNIXTIME 转换函数)

SELECT SQL_NO_CACHE
    measured_on
FROM
    vertabelo.inttimestampmeasures m
WHERE
    WEEKDAY(FROM_UNIXTIME(m.measured_on)) = 0 #MONDAY;
Response time (ms) Sysbench mysqlslap
Min 2051 5844
Max 7007 10469
Average 3486 8088

 

结论

  • 两个基准测试工具都表明 datime 比 timestamp 和 int(使用转换函数) 快
  • 但在这个测试中,int(使用转换函数)比 timestamp 更快
Avg response time (ms) Sysbench 相对于 datetime 的速度 mysqlslap 相对于 datetime 的速度
Datetime 3127 - 6103 -
Timestamp 3653 17% slower 8412 38% slower
INT 3486 11% slower 8088

32% slower

 

测试三:统计星期一的数据量


下列查询均是从 1,497,421 个可用数据中返回 1 行

datetime

SELECT SQL_NO_CACHE 
    COUNT(measured_on)
FROM
    vertabelo.datetimemeasures m
WHERE
    WEEKDAY(m.measured_on) = 0 #MONDAY;
Response time (ms) Sysbench mysqlslap
Min 1720 4063
Max 4594 7812
Average 2797 5540

 

timestamp

SELECT SQL_NO_CACHE
    COUNT(measured_on)
FROM
    vertabelo.timestampmeasures m
WHERE
    WEEKDAY(m.measured_on) = 0 #MONDAY;
Response time (ms) Sysbench mysqlslap
Min 1907 4578
Max 5437 10235
Average 3408 7102

 

int(使用 FROM_UNIXTIME 转换函数)

SELECT SQL_NO_CACHE
    COUNT(measured_on)
FROM
    vertabelo.inttimestampmeasures m
WHERE
    WEEKDAY(FROM_UNIXTIME(m.measured_on)) = 0 #MONDAY;
Response time (ms) Sysbench mysqlslap
Min 2108 5609
Max 4764 9735
Average 3307 7416

 

结论

  • 两个基准测试工具都表明 datime 比 timestamp 和 int(使用转换函数) 快
  • 但在这个测试中,int(使用转换函数)比 timestamp 更快

 

Avg response time (ms) Sysbench 相对于 datetime 的速度 mysqlslap 相对于 datetime 的速度
Datetime 2797 - 5540 -
Timestamp 3408 22% slower 7102 28% slower
INT 3307 18% slower 7416 33% slower

 

最终结论


使用 datetime 应该是绝大多数场景下的最佳选择,因为

  • 它更快
  • 它可读性更好,无需转换
  • 没有时区切换的问题
  • 它仅比 timestamp 多使用 1 个字节,但存储的时间范围却非常大

 

做抉择

  • 如果只是想存储简单的 unix 时间戳,那么使用 int 是最佳选择,因为它非常快,和使用普通数字一样
  • 而如果要根据时区进行存储日期时间,那么就应该使用 timestamp
  • 否则绝大多数情况下推荐使用  datetime
相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
相关文章
|
存储 关系型数据库 MySQL
【免费动手教程上线】阿里云RDS MySQL推出大容量高性能存储:高性能本地盘(最高16TB存储空间)、高性能云盘(最高64TB存储空间)
阿里云RDS MySQL提供高性能本地盘与高性能云盘等存储方案,满足用户大容量、低延迟需求。高性能本地盘单盘最大16TB,IO延时微秒级;高性能云盘兼容ESSD特性,支持IO性能突发、BPE及16K原子写等能力。此外,阿里云还提供免费动手体验教程,帮助用户直观感受云数据库 RDS 存储性能表现。
|
存储 SQL 关系型数据库
【YashanDB知识库】MySQL迁移至崖山char类型数据自动补空格问题
**简介**:在MySQL迁移到崖山环境时,若字段类型为char(2),而应用存储的数据仅为&#39;0&#39;或&#39;1&#39;,查询时崖山会自动补空格。原因是mysql的sql_mode可能启用了PAD_CHAR_TO_FULL_LENGTH模式,导致保留CHAR类型尾随空格。解决方法是与应用确认数据需求,可将崖山环境中的char类型改为varchar类型以规避补空格问题,适用于所有版本。
|
Python Windows
[oeasy]python076_int这个词怎么来的_[词根溯源]整数类型_int_integer_touch
本文探讨了“int”一词的起源及其与整数类型的关联。通过词根溯源,揭示“int”来源于“integer”,意为“完整的数”,与零碎的分数相对。同时分析了相关词汇如“tact”(接触)、“touch”(触摸)及衍生词,如“tangential”(切线的)、“intagible”(无形的)和“integral”(完整的、不可或缺的)。文章还结合编程语言特性,解释了Python作为动态类型、强类型语言的特点,并总结了整型变量的概念与意义。最后预告了后续内容,提供了学习资源链接。
706 11
|
关系型数据库 MySQL Java
【YashanDB知识库】崖山BIT类型对MYSQL兼容问题
【YashanDB知识库】崖山BIT类型对MYSQL兼容问题
|
自然语言处理 关系型数据库 MySQL
MySQL索引有哪些类型?
● 普通索引:最基本的索引,没有任何限制。 ● 唯一索引:索引列的值必须唯一,但可以有空值。可以创建组合索引,则列值的组合必须唯一。 ● 主键索引:是特殊的唯一索引,不可以有空值,且表中只存在一个该值。 ● 组合索引:多列值组成一个索引,用于组合搜索,效率高于索引合并。 ● 全文索引:对文本的内容进行分词,进行搜索。
|
存储 C语言 Python
[oeasy]python077_int类型怎么用_整数运算_integer_进制转化_int类
本文主要讲解了Python中`int`类型的应用与特性。首先回顾了`int`词根的溯源,探讨了整型变量的概念及命名规则(如匈牙利命名法)。接着分析了整型变量在内存中的存储位置和地址,并通过`type()`和`id()`函数验证其类型和地址。还介绍了整型变量的运算功能,以及如何通过`int()`函数将字符串转化为整数,支持不同进制间的转换(如二进制转十进制)。此外,文章提及了关键字`del`的使用场景,对比了Python与C语言中`int`的区别,并总结了整型与字符串类型的差异,为后续深入学习奠定基础。
539 1
|
机器学习/深度学习 关系型数据库 MySQL
mysql bit对gorm使用何种类型?
在GORM中使用MySQL的BIT类型时,通常使用 `bool`类型来处理BIT(1),使用 `[]byte`类型来处理BIT(N)(N > 1)。通过正确的类型映射和位操作,可以高效地处理位字段数据。确保在定义结构体字段时,明确指定字段类型,以便GORM能够正确地处理数据库交互。
478 18
|
存储 关系型数据库 MySQL
MySQL进阶突击系列(09)数据磁盘存储模型 | 一行数据怎么存?
文中详细介绍了MySQL数据库中一行数据在磁盘上的存储机制,包括表空间、段、区、页和行的具体结构,以及如何设计和优化行数据存储以提高性能。
|
存储 关系型数据库 MySQL
mysql怎么查询longblob类型数据的大小
通过本文的介绍,希望您能深入理解如何查询MySQL中 `LONG BLOB`类型数据的大小,并结合优化技术提升查询性能,以满足实际业务需求。
826 6

推荐镜像

更多