首页 > 数据库 >mysql数据库时间类型数据存储建议

mysql数据库时间类型数据存储建议

时间:2023-02-02 15:14:37浏览次数:40  
标签:00 01 zone Timestamp 数据库 mysql 存储 时间 time

本文转载自:https://javaguide.cn/database/mysql/some-thoughts-on-database-storage-time.html

 

我们平时开发中不可避免的就是要存储时间,比如我们要记录操作表中这条记录的时间、记录转账的交易时间、记录出发时间等等。你会发现时间这个东西与我们开发的联系还是非常紧密的,用的好与不好会给我们的业务甚至功能带来很大的影响。所以,我们有必要重新出发,好好认识一下这个东西。

这是一篇短小精悍的文章,仔细阅读一定能学到不少东西!

不要用字符串存储日期

我记得我在大学的时候就这样干过,而且现在很多对数据库不太了解的新手也会这样干,可见,这种存储日期的方式的优点还是有的,就是简单直白,容易上手。

但是,这是不正确的做法,主要会有下面两个问题:

  1. 字符串占用的空间更大!
  2. 字符串存储的日期效率比较低(逐个字符进行比对),无法用日期相关的 API 进行计算和比较。

 Datetime 和 Timestamp 之间抉择

Datetime 和 Timestamp 是 MySQL 提供的两种比较相似的保存时间的数据类型。他们两者究竟该如何选择呢?

通常我们都会首选 Timestamp。 下面说一下为什么这样做!

 DateTime 类型没有时区信息

DateTime 类型是没有时区信息的(时区无关) ,DateTime 类型保存的时间都是当前会话所设置的时区对应的时间。这样就会有什么问题呢?当你的时区更换之后,比如你的服务器更换地址或者更换客户端连接时区设置的话,就会导致你从数据库中读出的时间错误。不要小看这个问题,很多系统就是因为这个问题闹出了很多笑话。

Timestamp 和时区有关。Timestamp 类型字段的值会随着服务器时区的变化而变化,自动换算成相应的时间,说简单点就是在不同时区,查询到同一个条记录此字段的值会不一样。

下面实际演示一下!

建表 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;

插入数据:

INSERT INTO time_zone_test(date_time,time_stamp) VALUES(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='+8:00';

再次查看数据:

+---------------------+---------------------+

| date_time           | time_stamp          |

+---------------------+---------------------+

| 2020-01-11 09:53:32 | 2020-01-11 17:53:32 |

+---------------------+---------------------+

扩展:一些关于 MySQL 时区设置的一个常用 sql 命令

# 查看当前会话时区
SELECT @@session.time_zone;
# 设置当前会话时区
SET time_zone = 'Europe/Helsinki';
SET time_zone = "+00:00";
# 数据库全局时区设置
SELECT @@global.time_zone;
# 设置全局时区
SET GLOBAL time_zone = '+8:00';
SET GLOBAL time_zone = 'Europe/Helsinki';  

 DateTime 类型耗费空间更大

Timestamp 只需要使用 4 个字节的存储空间,但是 DateTime 需要耗费 8 个字节的存储空间。但是,这样同样造成了一个问题,Timestamp 表示的时间范围更小。

  • DateTime :1000-01-01 00:00:00 ~ 9999-12-31 23:59:59
  • Timestamp: 1970-01-01 00:00:01 ~ 2037-12-31 23:59:59

Timestamp 在不同版本的 MySQL 中有细微差别。

数值型时间戳是更好的选择吗?

很多时候,我们也会使用 int 或者 bigint 类型的数值也就是时间戳来表示时间。

这种存储方式的具有 Timestamp 类型的所具有一些优点,并且使用它的进行日期排序以及对比等操作的效率会更高,跨系统也很方便,毕竟只是存放的数值。缺点也很明显,就是数据的可读性太差了,你无法直观的看到具体时间。

时间戳的定义如下:

时间戳的定义是从一个基准时间开始算起,这个基准时间是「1970-1-1 00:00:00 +0:00」,从这个时间开始,用整数表示,以秒计时,随着时间的流逝这个时间整数不断增加。这样一来,我只需要一个数值,就可以完美地表示时间了,而且这个数值是一个绝对数值,即无论的身处地球的任何角落,这个表示时间的时间戳,都是一样的,生成的数值都是一样的,并且没有时区的概念,所以在系统的中时间的传输中,都不需要进行额外的转换了,只有在显示给用户的时候,才转换为字符串格式的本地时间。

数据库中实际操作:

mysql> select UNIX_TIMESTAMP('2020-01-11 09:53:32');

1578707612

mysql> select FROM_UNIXTIME(1578707612);

2020-01-11 09:53:32  

总结

MySQL 中时间到底怎么存储才好?Datetime?Timestamp? 数值保存的时间戳?

好像并没有一个银弹,很多程序员会觉得数值型时间戳是真的好,效率又高还各种兼容,但是很多人又觉得它表现的不够直观。这里插一嘴,《高性能 MySQL 》这本神书的作者就是推荐 Timestamp,原因是数值表示时间不够直观。

每种方式都有各自的优势,根据实际场景才是王道。下面再对这三种方式做一个简单的对比,以供大家实际开发中选择正确的存放时间的数据类型:

 

 

标签:00,01,zone,Timestamp,数据库,mysql,存储,时间,time
From: https://www.cnblogs.com/caroline2016/p/17086064.html

相关文章

  • sql语句在mysql中的执行过程
    本文转载自:https://javaguide.cn/database/mysql/how-sql-executed-in-mysql.html 一MySQL基础架构分析 1.1MySQL基本架构概览下图是MySQL的一个简要架构图,从......
  • mysql索引详解
    本文转载自https://javaguide.cn/database/mysql/mysql-index.html索引介绍索引是一种用于快速查询和检索数据的数据结构,其本质可以看成是一种排序好的数据结构。索引......
  • mysql查询优化工具
    本文转载自https://www.cnblogs.com/yidengjiagou/p/16594161.html optimizertraceoptimizertrace 可以帮助我们查看优化器生成执行计划的整个过程,以及做出的各种决......
  • Mysql事务底层原理
    本文转载自https://www.cnblogs.com/yidengjiagou/p/16413825.html 事务有四大特性,分别是原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability),简称......
  • python数据持久存储:pickle模块的使用
    python的pickle模块实现了基本的数据序列和反序列化。通过pickle模块的序列化操作我们能够将程序中运行的对象信息保存到文件中去,永久存储;通过pickle模块的反序列化操作,我们......
  • mysql创建还原点
    setautocommit=0;insertintot1(name)values("user1");savepointp1;insertintot1(name)values("user2");svaepointp2;insertintot1(name)values("user3")......
  • Mysql导出大量数据
    outfile导出文件selectnamefromt1intooutfile"/tmp/test.txt"infile导入文件导入到表t1中的name列loaddatainfile"/tmp/test.txt"intotablet1(name);导入......
  • sql_server数据库
    问题:如何在SQLSERVER中合并时间和日期?解决方法1:使用+合并时间日期让我们运行以下命令:SELECTCAST(字段名ASDATETIME)+CAST(字段名ASDATETIME)AS[CombineDateTime......
  • 若依-更换数据库-sqlite
    基础我是在ruoyi-vue已经安装了mybatis-plus的基础上进行的修改关于SQLiteSQLite是一个软件库,实现了自给自足的、无服务器的、零配置的、事务性的SQL数据库引擎。SQ......
  • MySQL隔离级别、锁、SQL优化
    一、事务隔离级别1.1事务-事务是逻辑上的一组操作,要么全部执行,要么全部不执行。-事务(Transaction)是并发控制单位,是用户定义的一个操作序列,这些操作要么都做,要么都不......