Mysql timestamp和datetime区别

文章目录

      • 一、存储范围和精度
      • 二、默认值和自动更新
      • 三、时区处理
      • 四、索引和性能
      • 五、存储空间和数据复制
      • 六、使用场景和注意事项
      • 七、时区转换

MySQL是一个常用的关系型数据库管理系统,其内置了多种数据类型用于存储和操作数据。其中,timestamp和datetime是两种常用的日期和时间类型,在实际应用中经常被使用。本文将从不同的角度分析二者的区别,并结合案例和代码进行比较说明。

一、存储范围和精度

  1. datetime:存储范围为’1000-01-01 00:00:00’到’9999-12-31 23:59:59’,默认精度为秒。
  2. timestamp:存储范围为’1970-01-01 00:00:01’到’2038-01-19 03:14:07’,默认精度为秒。

可以看出,datetime的存储范围和精度更大,能够表示更远的时间。

MySQL的timestamp类型的精确度是秒级。如果需要更高的精确度(比如毫秒或微秒),则需要使用datetime类型。datetime(3) 提供了毫秒级的精确度,而datetime(6) 提供了微秒级的精确度。

如果你在创建表时需要包含MySQL时间戳字段,并希望它具有毫秒级的精确度,你应该这样做:

CREATE TABLE example_table (id INT AUTO_INCREMENT PRIMARY KEY,description VARCHAR(255),created_at DATETIME(3) DEFAULT CURRENT_TIMESTAMP(3)
);

在这个例子中,created_at字段定义为DATETIME(3)类型,这意味着它将存储毫秒级精度的时间戳。DEFAULT CURRENT_TIMESTAMP(3)设置了该字段的默认值为当前时间(包含毫秒精度)。

如果你需要微秒级精确度,你只需将3改为6

CREATE TABLE example_table (id INT AUTO_INCREMENT PRIMARY KEY,description VARCHAR(255),created_at DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6)
);

在这个示例中,created_at字段将存储微秒级精度的时间戳。

二、默认值和自动更新

  1. 默认值:

    • datetime:可以指定默认值,例如’2022-01-01 00:00:00’。
    • timestamp:如果未显式指定默认值或插入相应列时,将自动设置为当前时间。
  2. 自动更新:

    • datetime:不支持自动更新,需要手动更新。
    • timestamp:支持自动更新,可通过触发器或ON UPDATE CURRENT_TIMESTAMP选项实现。

例如,创建一张用户表,包含注册时间(datetime类型)和最后更新时间(timestamp类型)两个字段:

CREATE TABLE user (registration_time datetime DEFAULT '2022-01-01 00:00:00',last_update_time timestamp ON UPDATE CURRENT_TIMESTAMP
);

在插入用户数据时,可以看到注册时间是固定的,而最后更新时间会自动更新。

三、时区处理

  1. datetime:不存储时区信息,插入的时间值会被当做服务器的本地时间存储。
  2. timestamp:存储的是UTC时间,并在检索时会根据系统时间和时区设置转换成本地时间。

例如,设置MySQL服务器时区为UTC+8,插入当前时间:

INSERT INTO user (registration_time, last_update_time) VALUES (NOW(), NOW());

存储在datetime类型的字段中的时间会直接是服务器的本地时间;而存储在timestamp类型的字段中的时间会转换成UTC时间,并加上8个小时。

四、索引和性能

  1. datetime:在使用datetime作为索引列时,MySQL会对整个日期时间值进行索引,因此可以精确匹配。
  2. timestamp:在使用timestamp作为索引列时,MySQL只对其中的日期进行索引,忽略时间部分,因此只能匹配到日期相同的记录。

例如,创建一个用户订单表,包含订单时间(datetime类型)和支付时间(timestamp类型)两个字段,同时为这两个字段创建索引:

CREATE TABLE orders (order_time datetime,payment_time timestamp
);CREATE INDEX idx_order_time ON orders (order_time);
CREATE INDEX idx_payment_date ON orders (DATE(payment_time));

在此例中,通过查询订单时间可以使用datetime类型的索引,进行精确匹配;而通过支付时间只能使用日期部分进行索引匹配,忽略具体的时间,降低了查询的精确性。

五、存储空间和数据复制

  1. 存储空间:

    • TIMESTAMP类型使用4个字节的存储空间,存储范围为’1970-01-01 00:00:01’ UTC 到 ‘2038-01-19 03:14:07’ UTC。
    • DATETIME类型使用8个字节的存储空间,存储范围为’1000-01-01 00:00:00’到’9999-12-31 23:59:59’。
  2. 数据复制:

    • TIMESTAMP值在数据传输过程中(如复制数据、远程备份等)会自动转换为UTC时间(全球标准时间),在目标系统上根据其时区设置转换为当地时间。这意味着,如果源系统和目标系统的时区设置不同,TIMESTAMP字段的值可能会发生变化。
    • DATETIME值在数据传输过程中保持不变,不考虑时区设置。这意味着,无论源系统和目标系统的时区设置如何,DATETIME字段的值都保持一致。

这些差异使得TIMESTAMP和DATETIME在不同的应用场景中各有优势。例如,如果希望在世界范围内统一处理时间(如在分布式系统中),可能会选择TIMESTAMP;如果希望保存历史事件的确切日期和时间,可能会选择DATETIME。

六、使用场景和注意事项

使用场景:

  • TIMESTAMP通常用于记录特定事件发生的具体时间,如用户注册时间,用户登陆时间等。
  • DATETIME通常用于记录未来的日期时间,或者需要保存年份比较大或者比较小的时间。

注意事项:

  • 使用TIMESTAMP时要注意它的时间范围,避免超出。
  • 基于TIMESTAMP的时区转换特性,如果你的应用运行在多个时区,而你又希望所有用户在查看同一时间字段时看到一样的值,那么应该使用DATETIME。
  • 为了获取准确的结果,最好在应用程序中处理日期和时间的运算,而不是依赖于SQL。
-- 创建一个名为example的数据库
CREATE DATABASE example;
USE example;-- 创建一个名为timetable的表,包含一个TIMESTAMP和一个DATETIME列
CREATE TABLE timetable (event_timestamp TIMESTAMP,event_datetime DATETIME
);-- 插入一条记录,使用当前时间作为值
INSERT INTO timetable (event_timestamp, event_datetime) VALUES (CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP());-- 查询记录,观察输出结果
SELECT * FROM timetable;

这个例子演示了使用TIMESTAMP和DATETIME插入和查询数据。在插入一条记录时,TIMESTAMP和DATETIME列都使用了CURRENT_TIMESTAMP()函数来获取当前的时间。然后,通过查询SELECT * FROM timetable;来获取这条记录的所有列。

TIMESTAMP列在查询结果中可能显示的时间与插入时不完全相同,这是因为TIMESTAMP在存储时被转换为了当前时区的时间。换句话说,查询结果是当前时区的时间版本。而DATETIME列则会原样输出插入时的时间值,不受时区影响。

这个示例可以帮助您更好地理解TIMESTAMP和DATETIME在实际使用中的区别和行为差异。

七、时区转换

一个重要的区别在于时区处理。在应用中,我们经常需要处理不同时区的日期和时间,而timestamp和datetime在时区转换方面表现不同。

  1. datetime:datetime类型的值没有时区信息,它被视为服务器本地时间。如果我们在一个具有时区差异的环境中使用datetime值,可能会导致时区处理不准确。

  2. timestamp:timestamp类型存储的是UTC时间,但当我们从数据库中检索数据时,它会自动根据系统时区和连接会话时区进行转换成本地时间。

下面通过一个例子来说明这一点。假设有一个应用需要记录用户的登录时间,它支持国际化,用户分布在不同的时区。我们使用timestamp和datetime来存储登录时间。

CREATE TABLE user_login (user_id INT,login_time_datetime DATETIME,login_time_timestamp TIMESTAMP
);
  1. 使用datetime存储登录时间:
INSERT INTO user_login (user_id, login_time_datetime) VALUES (1, '2022-03-13 13:30:00');

当用户登录的时候,我们获取用户所在时区,并将登录时间转换为该时区的本地时间。

import pytz
from datetime import datetimeuser_timezone = pytz.timezone('Asia/Shanghai')
login_time = datetime(2022, 3, 13, 13, 30, 0, tzinfo=pytz.utc).astimezone(user_timezone)print(login_time)

在这个例子中,我们假设用户位于上海时区(Asia/Shanghai),将UTC时间转换为用户本地时间。但是,如果我们从数据库中检索登录时间并显示给用户时,可能会出现问题,因为登录时间没有时区信息,可能会被错误地解释为用户本地时间。

  1. 使用timestamp存储登录时间:
INSERT INTO user_login (user_id, login_time_timestamp) VALUES (1, '2022-03-13 13:30:00');

当用户登录的时候,我们直接将UTC时间存储在timestamp类型的字段中,不需要进行时区转换。

import pytz
from datetime import datetimeuser_timezone = pytz.timezone('Asia/Shanghai')
login_time = datetime(2022, 3, 13, 13, 30, 0, tzinfo=pytz.utc)print(login_time)

在这个例子中,我们同样假设用户位于上海时区,但是由于timestamp类型存储的是UTC时间,不需要进行时区转换。当我们从数据库中检索登录时间时,它会自动根据用户所在时区进行转换,并返回正确的登录时间。

通过这个例子,我们可以看到timestamp类型在处理时区转换方面的优势。在设计应用中涉及到跨时区的日期和时间存储时,timestamp类型是更可取的选择。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/201351.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

分包(微信小程序)

首先,微信小程序中使用分包是为了减少首屏的请求,因为微信小程序会默认下载主包内的内容并展示到页面上,但是随着业务量的增加,代码量也会越来越大。会导致我们启动小程序的时候首页加载速度过慢的这个问题。这时我们就可以采用分…

C语言-字符串函数

字符串 1. 字符串处理函数 1. strlen:长度 作用:测量字符串长度 语法: size_t strlen(const char *s);参数: s:要测量的字符指针变量 返回值: 字符串长度 注意:不包含 ‘\0’ sizeof 是个关…

研习代码 day49 | 动态规划——子序列问题(回文)

一、回文子串(连续) 1.1 题目 给你一个字符串 s ,请你统计并返回这个字符串中 回文子串 的数目。 回文字符串 是正着读和倒过来读一样的字符串。 子字符串 是字符串中的由连续字符组成的一个序列。 具有不同开始位置或结束位置的子串&#xf…

解决(error) ERR Errors trying to SHUTDOWN. Check logs.问题~

该问题出现在我在使用shutdown关闭redis服务器时,出现该问题的原因是由于配置文件的日志文件位置未配置或者缺少日志文件 我自己出现该问题是因为缺少日志文件,解决步骤如下所示: 第一步:在该目录下使用touch命令创建日志文件 第…

【工具与中间件】快速构建飞书群聊机器人

文章目录 0. 前言1. 无痛入门1.1 飞书创建群聊机器人1.2 Webhook 请求示例1.3 设置安全策略 2. 实战3. 总结3.1 使用体验3.2 深入使用建议 先进团队用飞书,先进飞书群聊有...... 0. 前言 科技蓬勃发展的今天,我们可以轻松拥有属于自己/团队的机器人。日…

Ubuntu18.04 本地安装CVAT标注工具

写在前面: 1、如果直接clone最新版本的cvat,python版本最好安装3.8的,因为其中部分代码的语法只有高版本的python才可以支持。 2、安装完成以后本地登陆可能出现"cannot connect to cvat server"的错误,可以从Cannot …

制作麒麟oem镜像之通过识别终端品牌与BIOS安装不同内容

原文链接:麒麟oem镜像之识别终端品牌与BIOS安装不同内容 **hello,大家好啊!**在个性化和定制化日益成为趋势的今天,操作系统的定制化安装也变得越来越重要。特别是对于企业用户来说,能够根据不同的硬件配置和需求&…

项目实战之RabbitMQ重试机制进行消息补偿通知

🧑‍💻作者名称:DaenCode 🎤作者简介:啥技术都喜欢捣鼓捣鼓,喜欢分享技术、经验、生活。 😎人生感悟:尝尽人生百味,方知世间冷暖。 文章目录 🌟架构图&#x…

Python Tkinter库入门与基础

更多资料获取 📚 个人网站:ipengtao.com Tkinter是Python标准库中内置的图形用户界面(GUI)工具包,提供了创建窗口、按钮、文本框等GUI元素的功能。本文将介绍Tkinter的基础知识,帮助大家快速入门。 安装与…

【华为OD题库-066】冠亚军排名-java

题目 2012伦敦奥运会即将到来,大家都非常关注奖牌榜的情况,现在我们假设奖牌榜的排名规则如下. 1.首先gold medal数量多的排在前面 2.其次silver medal数量多的排在前面 3.然后bronze medal数量多的排在前面 4.若以上三个条件仍无法区分名次,…

【OpenGauss源码学习 —— (VecToRow)算子】

VecToRow 算子 概述ExecInitVecToRow 函数功能参数步骤 ExecVecToRow 函数功能描述参数返回值执行步骤DevectorizeOneBatch 函数 ExecEndVecToRow 函数总结 声明:本文的部分内容参考了他人的文章。在编写过程中,我们尊重他人的知识产权和学术成果&#x…

低成本物联网安全芯片ACL16_S 系列,可应用物联网认证、 SIM、防抄板和设备认证等产品上

ACL16_S 芯片是针对物联网认证、 SIM、防抄板和设备认证需求推出的高安全芯片。芯片采用 32 位 ARMCortex™-M0 系列内核,片内集成多种安全密码模块,包括 RSA/ECC DES/TDES、 SHA-1/-256、 AES-128/-192/-256 等国际安全算法,支持真随机数发…

岳阳楼3D模型纹理贴图

在线工具推荐: 3D数字孪生场景编辑器 - GLTF/GLB材质纹理编辑器 - 3D模型在线转换 - Three.js AI自动纹理开发包 - YOLO 虚幻合成数据生成器 - 三维模型预览图生成器 - 3D模型语义搜索引擎 岳阳楼,位于湖南省岳阳市岳阳楼区洞庭北路,地…

Vcenter 6.7 VCSA证书过期问题处理

1. 故障现象 2022年10月25日,登陆VC报错。 按照报错信息,结合官方文档,判断为STS证书过期导致。 vCenter Server Appliance (VCSA) 6.5.x, 6.7.x or vCenter Server 7.0.x 在/var/log/vmware/vpxd-svcs/vpxd-svcs.log看到类似报错: ERRO…

为什么程序员会讨厌PHP编程语言?

闲来无事,逛了某乎看见一篇关于PHP编程的学习指南,深受启发。我们都知道PHP是一种流行的爬虫语言,尤其在Web开发方面。太有很多有点,例如简单易学、支持的成许多等。但是PHP也会存在一些缺点,如代码可读性差&#xff0…

【Java 基础】20 多线程操作方法

文章目录 1.获取和设置线程的名字1)获取默认名字2)获取自定义的名字 2.判断线程是否启动3.线程的强制执行4.让线程睡一会儿5.中断线程6.守护线程7.线程的礼让 前一节我们介绍了线程的定义、创建方法、状态以及各状态间的转换。在状态转换处只是简单的说明…

Windows下Linkis1.5DSS1.1.2本地调试

1 Linkis: 参考: 单机部署 | Apache Linkis技术分享 | 在本地开发调试Linkis的源码 (qq.com)DataSphere Studio1.0本地调试开发指南 - 掘金 (juejin.cn) 1.1 后端编译 参考【后端编译 | Apache Linkis】】 修改linkis模块下pom.xml,将mysql.connetor.scope修改…

C语言速通笔记(41-62)

40.十六进制转义字符:\x6d才是合法的,前面的0不能写,而且 x 是小写 41.字符型和整型是近亲:两个具有很大的相似之处,所有的字符都有一个它对应的整形数 据的 ASCLL 的数值。如 char a 65 % …

Java Socket编程之基于UDP协议通信

1.说明 Socket(套接字)是计算机网络编程中用于实现网络通信的一种编程接口或抽象概念。 它提供了一种标准的接口,使应用程序能够通过网络与其他计算机进行通信。 Socket可以看作是应用程序与网络之间的一个通信端点,类似于电话中…

go-fastfds部署心得

我是windows系统安装 Docker Desktop部署 docker run --name go-fastdfs(任意的一个名称) --privilegedtrue -t -p 3666:8080 -v /data/fasttdfs_data:/data -e GO_FASTDFS_DIR/data sjqzhang/go-fastdfs:lastest docker run:该命令用于运…