mysql timestamp字段规范使用详情
怎么入门数据库编程?需要学习哪些知识点?这是新手们刚接触编程时常见的问题;下面golang学习网就来给大家整理分享一些知识点,希望能够给初学者一些帮助。本篇文章就来介绍《mysql timestamp字段规范使用详情》,涉及到字段、mysqltimestamp,有需要的可以收藏一下
1. 前言
这个世界离不开时间,同样,数据库中也是如此,表中的每条记录除了数据模型的时间字段(如生日,生产日期,出发日期等),一般至少还有两个固定的时间字段:记录插入时间,记录更新时间。
然而,看似很简单时间字段,谁能想到会导致应用报错,引发血案:

个中缘由,正是接下来要讲到的。
2. mysql中的时间字段
因时间字段的一些特性与版本有关,且目前我司统一使用的mysql 5.7版本,因此本文内容都基于mysql 5.7。
mysql时间相关的字段主要有DATE、DATETIME、TIMESTAMP。

其中datatime和timestamp字段都可以包含小数,如datetime(6),字节长度的可变部分(0-3)由小数位数决定:

2.1. 数据的存储方式
DATE:
3个字节的整型,按照这种方式进行压缩: YYYY×16×32 + MM×32 + DD
DATETIME:
整数部分5个字节,由以下部分组成

TIMESTAMP:
整数部分4个字节,存储从(‘1970-01-01 00:00:00’ UTC)到指定时间的秒数;
timestamp类型是4个字节,最大值是2的31次方减1,也就是2147483647,转换成北京时间就是2038-01-19 11:14:07
2.2. DATETIME和TIMESTMAP的区别
- 数据的存储方式决定了timestamp的计算和索引效率比datetime更快;
- timestamp存储的时间范围比datetime小很多;
- timestamp数据显示时要根据时区换算,datetime数据显示时不受时区影响;
admin@test 04:42:41>show variables like 'time_zone'; +---------------+--------+ | Variable_name | Value | +---------------+--------+ | time_zone | +08:00 | +---------------+--------+ admin@test 04:42:42>create table t1(dt datetime,ts timestamp); admin@test 04:43:07>insert into t1 values(now(),now()); admin@test 04:43:17>select * from t1; +---------------------+---------------------+ | dt | ts | +---------------------+---------------------+ | 2021-03-27 16:43:17 | 2021-03-27 16:43:17 | +---------------------+---------------------+ admin@test 04:43:50>set time_zone='+09:00'; admin@test 04:44:00>select * from t1; +---------------------+---------------------+ | dt | ts | +---------------------+---------------------+ | 2021-03-27 16:43:17 | 2021-03-27 17:43:17 | +---------------------+---------------------+ admin@test 04:44:07>
timestamp在处理默认值和null值时的行为时受mysql参数explicit_defaults_for_timestamp控制,datatime不受影响。
3. timestamp字段处理默认值和null值时的行为
3.1. 参数禁用
当禁用该值时(explicit_defaults_for_timestamp=0),mysql启用timestamp字段的特有行为(和数字、字符串等类型的表现不同),
具体特性如下:
- timestamp字段默认设置为not null
- 表中的第一个timestamp字段插入时默认设置当前时间,更新时,默认更新为当前时间,即默认设置为以下特性:NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
- 表中的第二个timestamp字段默认为'0000-00-00 00:00:00'
- 显式向timestamp字段插入null值时,不会报错,且都设置为当前时间;
- 对datetime字段的行为无影响。
admin@test 05:49:00>create table t2(id int auto_increment, name varchar(100), dt1 datetime, ts1 timestamp, ts2 timestamp, primary key(id)); admin@test 05:49:48>show create table t2; ±------±--------------------------------------------------------------------------+ | Table | Create Table | ±------±--------------------------------------------------------------------------+ | t2 | CREATE TABLE t2 ( id int(11) NOT NULL AUTO_INCREMENT, name varchar(100) DEFAULT NULL, dt1 datetime DEFAULT NULL, ts1 timestamp NULL DEFAULT NULL, ts2 timestamp NULL DEFAULT NULL, PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 | ±------±--------------------------------------------------------------------------+ 1 row in set (0.00 sec) admin@test 05:50:20>insert into t2(name) values(‘a1'); Query OK, 1 row affected (0.00 sec) admin@test 05:51:07>select * from t2; ±—±-----±-----±-----±-----+ | id | name | dt1 | ts1 | ts2 | ±—±-----±-----±-----±-----+ | 1 | a1 | NULL | NULL | NULL | ±—±-----±-----±-----±-----+ 1 row in set (0.00 sec) ##注:插入记录时,默认为null admin@test 05:54:20>update t2 set name=‘aa1' where id=1; Query OK, 1 row affected (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 0 admin@test 05:54:31>select * from t2; ±—±-----±-----±-----±-----+ | id | name | dt1 | ts1 | ts2 | ±—±-----±-----±-----±-----+ | 1 | aa1 | NULL | NULL | NULL | ±—±-----±-----±-----±-----+ 1 row in set (0.00 sec) ##注:更新记录时,默认为null admin@test 05:58:10>create table t3(id int auto_increment,name varchar(100),ts1 timestamp not null default current_timestamp,primary key(id)); admin@test 05:58:18>insert into t3(name) values(‘a1'); Query OK, 1 row affected (0.00 sec) admin@test 05:58:22>select * from t3; ±—±-----±--------------------+ | id | name | ts1 | ±—±-----±--------------------+ | 1 | a1 | 2021-03-23 17:58:22 | ±—±-----±--------------------+ 1 row in set (0.00 sec) ##注:创建表手动设置not null default current_timestamp,插入记录不含timestamp字段时,默认为当前时间 admin@test 05:58:25>insert into t3(name,ts1) values(‘a1',null); ERROR 1048 (23000): Column ‘ts1' cannot be null ##注:timestamp字段显式插入null时,报错Column ‘ts1' cannot be null admin@test 05:59:11>create table t4(id int auto_increment,name varchar(100),ts1 timestamp not null ,primary key(id)); Query OK, 0 rows affected (0.04 sec) admin@test 05:59:44>insert into t4(name) values(‘a1'); ERROR 1364 (HY000): Field ‘ts1' doesn't have a default value admin@test 05:59:49> ##注:创建表手动设置not null,插入记录不含timestamp字段时,报错Field doesn't have a default value admin@test 05:59:50>insert into t4(name,ts1) values(‘a1',null); ERROR 1048 (23000): Column ‘ts1' cannot be null admin@test 05:59:57> ##注:timestamp字段显式插入null时,报错Column ‘ts1' cannot be null
3.2. 参数启用
当启用该值时(explicit_defaults_for_timestamp=1),mysql禁用timestamp字段的特有行为,具体表现和数字、字符串类型一样。
- timestamp字段默认属性是“NULL DEFAULT NULL”;
- timestamp字段手动设置了not null和default后,显式插入null值会报错:Column cannot be null;
- timestamp字段同时设置了not null但未设置default后,显式插入null值会报错:Column cannot be null,插入记录不含timestamp字段时会报错Field doesn’t have a default value;
- 对datetime字段的行为无影响。
admin@test 05:49:00>create table t2(id int auto_increment, name varchar(100), dt1 datetime, ts1 timestamp, ts2 timestamp, primary key(id));
admin@test 05:49:48>show create table t2;
+-------+---------------------------------------------------------------------------+
| Table | Create Table |
+-------+---------------------------------------------------------------------------+
| t2 | CREATE TABLE `t2` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(100) DEFAULT NULL,
`dt1` datetime DEFAULT NULL,
`ts1` timestamp NULL DEFAULT NULL,
`ts2` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 |
+-------+---------------------------------------------------------------------------+
1 row in set (0.00 sec)
admin@test 05:50:20>insert into t2(name) values(‘a1');
Query OK, 1 row affected (0.00 sec)
admin@test 05:51:07>select * from t2;
±—±-----±-----±-----±-----+
| id | name | dt1 | ts1 | ts2 |
±—±-----±-----±-----±-----+
| 1 | a1 | NULL | NULL | NULL |
±—±-----±-----±-----±-----+
1 row in set (0.00 sec)
## 注:插入记录时,默认为null
admin@test 05:54:20>update t2 set name=‘aa1' where id=1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
admin@test 05:54:31>select * from t2;
±—±-----±-----±-----±-----+
| id | name | dt1 | ts1 | ts2 |
±—±-----±-----±-----±-----+
| 1 | aa1 | NULL | NULL | NULL |
±—±-----±-----±-----±-----+
1 row in set (0.00 sec)
## 注:更新记录时,默认为null
admin@test 05:58:10>create table t3(id int auto_increment,name varchar(100),ts1 timestamp not null default current_timestamp,primary key(id));
admin@test 05:58:18>insert into t3(name) values(‘a1');
Query OK, 1 row affected (0.00 sec)
admin@test 05:58:22>select * from t3;
±—±-----±--------------------+
| id | name | ts1 |
±—±-----±--------------------+
| 1 | a1 | 2021-03-23 17:58:22 |
±—±-----±--------------------+
1 row in set (0.00 sec)
##注:创建表手动设置not null default current_timestamp,插入记录不含timestamp字段时,默认为当前时间
admin@test 05:58:25>insert into t3(name,ts1) values(‘a1',null);
ERROR 1048 (23000): Column ‘ts1' cannot be null
##注:timestamp字段显式插入null时,报错Column ‘ts1' cannot be null
admin@test 05:59:11>create table t4(id int auto_increment,name varchar(100),ts1 timestamp not null ,primary key(id));
Query OK, 0 rows affected (0.04 sec)
admin@test 05:59:44>insert into t4(name) values(‘a1');
ERROR 1364 (HY000): Field ‘ts1' doesn't have a default value
admin@test 05:59:49>
##注:创建表手动设置not null,插入记录不含timestamp字段时,报错Field doesn't have a default value
admin@test 05:59:50>insert into t4(name,ts1) values(‘a1',null);
ERROR 1048 (23000): Column ‘ts1' cannot be null
admin@test 05:59:57>
##注:timestamp字段显式插入null时,报错Column ‘ts1' cannot be null
4. 总结
启用该参数(explicit_defaults_for_timestamp=1)
timestamp字段在null、default属性的表现和其他普通字段表现类似:
- 如果没有显式设置default值,该值的维护完全需要应用程序显式插入和更新;
- 如果设置了not null,那么一定不能显式插入null值,否则应用会报错。
禁用该参数(explicit_defaults_for_timestamp=0)
timestamp字段在null、default属性的表现和其他普通字段表现有明显差异:
- 默认会设置NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;
- 显式插入null值,默认为当前时间,应用不会报错。
案例发生的场景:
公司所有集群已经统一启用该参数;
某集群过去某个时间因为研发的要求,将该参数禁用,但是这次集群切换后的新服务器采用了统一的参数模板,启用了参数;
应用程序显式向timestamp字段插入null值,且该字段已经设置了not null,在禁用该参数的集群不会报错,但是切换到启用了该参数的集群时,就报column cannot be null.
统一规范:
个别集群禁用该参数导致公司所有的mysql集群参数不统一,可能带来应用报错的后果,因此建议:
- 统一公司所有集群的参数explicit_defaults_for_timestamp=1;
- 用timestamp字段时设置default和not null属性;
- 应用程序不要显式插入null值。
到这里,我们也就讲完了《mysql timestamp字段规范使用详情》的内容了。个人认为,基础知识的学习和巩固,是为了更好的将其运用到项目中,欢迎关注golang学习网公众号,带你了解更多关于mysql的知识点!
MySQL执行计划详解
- 上一篇
- MySQL执行计划详解
- 下一篇
- Mysql系统变量与状态变量详细介绍
-
- 数据库 · MySQL | 5小时前 |
- MySQL 第几万页开始变慢:用稳定排序和游标条件替代深 OFFSET
- 405浏览 收藏
-
- 数据库 · MySQL | 9小时前 |
- MySQL JSON 数组检索要不要建多值索引:从 MEMBER OF 到不能排序的边界
- 463浏览 收藏
-
- 数据库 · MySQL | 21小时前 | MySQL · 连接管理 · 服务器配置 · max_connections MySQL 9.4 back_log 连接突发
- MySQL 9.4 为什么把 back_log 默认值提到 10000:连接突发时先看这条边界
- 488浏览 收藏
-
- 数据库 · MySQL | 1天前 | MySQL · InnoDB · server_memory · 内存配置 ·
- MySQL 9.4 的 server_memory 怎么用:限制默认内存估算,不是给 InnoDB 加缓存
- 215浏览 收藏
-
- 数据库 · MySQL | 4天前 |
- MySQL 8.4 隐藏索引怎么试:不删索引也能验证查询计划
- 133浏览 收藏
-
- 数据库 · MySQL | 5天前 |
- MySQL 分区表怎么处理跨分区唯一键:分区列约束与建表取舍
- 501浏览 收藏
-
- 数据库 · MySQL | 5天前 | MySQL · 数据库设计 · 索引优化 · mysql UUID_TO_BIN BIN_TO_UUID swap_flag 二进制UUID
- MySQL UUID_TO_BIN 如何保持时间有序:swap_flag 与 BIN_TO_UUID 还原边界
- 261浏览 收藏
-
- 数据库 · MySQL | 5天前 |
- MySQL 隐形列怎么兼容 SELECT *:INVISIBLE COLUMN 的灰度加字段方法
- 122浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- SuperCLUE
- SuperCLUE是权威的中文大语言模型综合评测基准,涵盖语言理解、知识应用、AI Agent智能体及安全性等12项核心能力。通过多轮对话与客观测试,定期发布榜单与技术报告,为模型研发、优化及行业选型提供科学依据。
- 136次使用
-
- C-Eval
- 深入了解C-Eval中文评估套件,涵盖52个学科与4级难度。本文详解其功能特点、Zero-shot/Few-shot使用方法及代码示例,助您全面评测LLM中文理解与泛化能力。
- 55次使用
-
- ClickPrompt
- ClickPrompt是一款专为AI提示词编写者设计的开源在线工具,支持Stable Diffusion绘图、ChatGPT对话及GitHub Copilot代码辅助。提供Prompt自动生成、一键运行、社区分享及可视化优化功能,帮助用户高效获取精准AI输出。
- 30次使用
-
- Stable Diffusion Prompt Book
- 深入解析OpenArt推出的Stable Diffusion Prompt Book,这本免费的开源提示词指南涵盖从基础语法到高级技巧,提供风格化词库与参数建议,助您优化AI绘画生成效果。
- 14次使用
-
- Google AI提示词库
- 探索Google Cloud官方生成式AI提示词库,提供免费、无需登录的中英双语Prompt模板。涵盖内容创作、代码优化、数据分析等场景,助您快速提升AI交互效率与质量。
- 32次使用
-
- golang中按照结构体的某个字段排序实例代码
- 2022-12-24 317浏览
-
- 对Golang中的FORM相关字段理解
- 2022-12-27 298浏览
-
- golang 实现两个结构体复制字段
- 2023-01-14 271浏览
-
- gorm update传入struct对象,零值字段不更新的解决方案
- 2023-01-07 341浏览
-
- golang中使用proto3协议导致的空值字段不显示的问题处理方案
- 2023-01-07 295浏览

