MYSQL timestamp用法

本文详细介绍了MySQL中Timestamp类型的使用方法,包括不同场景下的应用,如何自动更新记录创建和修改时间,以及如何读取时间戳。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题来源

在业务系统中,有时候想要知道用户最后一次活动距离现在的时间。记得mysql是有这样的字段的,可以直接在一条记录更新时,自动更新时间。上网查了查,找到了,是timestamp类型。

用法

在表中定义一个timestamp类型的字段,如下所示:

create table test(
    id integer primary key auto_increment,
    name varchar(256) not null,
    createdAt timestamp default current_timestamp on update current_timestamp
);

createdAt字段被定义为timestamp类型,而且默认值是当前时间戳,当记录发生更新时,该字段同时会更新为当前时间戳。timestamp等于是提供了对一条对数据自身修改时间的记录。
依据不同的场景,一般timestamp会有几类用法:

在记录创建修改时都刷新

参见上面的例子,在sql语句上,要同时注明default字段和on update字段。

createdAt timestamp default current_timestamp on update current_timestamp

只在记录创建时刷新时间,以后修改时不再刷新

如下所示,在定义字段时删去on update语句。

createdAt timestamp default current_timestamp

在创建时将字段设置为0,以后修改时刷新

只有on update语句。

createdAt timestamp on update current_timestamp

在创建时给一个定值,修改时刷新

只有on update语句。

createdAt timestamp DEFAULTyyyy-mm-dd hh:mm:ss' on update current_timestamp

这样,在记录发生变化时,可以根据需要记录时间戳。

字段更新值和原值一样的情况

假定我们更新了表的某个字段,例如name属性,createdAt也可以相应刷新。但是有一种情况例外,就是如果更新值和原值一样,mysql出于优化考虑,并不会执行任何操作。此时,为了记录时间,可以强制刷新时间戳。

update table test set name = '<new name>', createdAt = current_timestamp where id = 1;

读取时间戳

如果要读出时间戳,又该怎么使用呢?

select unix_timestamp(createdAt) as tt from test

如上所示,该语句可以读出来以秒为单位的时间戳,然后就可以进行各种比较和运算了。

<think>好的,用户想了解MySQL 5.7中timestamp用法。我需要先回忆一下timestamp类型的特点,尤其是5.7版本中的变化和注意事项。 首先,timestampMySQL中用于存储日期和时间,范围是从1970-01-01 00:00:01到2038-01-19 03:14:07,这是因为它占用4字节,和datetime不同。用户可能需要知道这个范围限制,特别是2038年的问题,这在5.7版本依然存在。 接下来,timestamp的时区处理。MySQL会将其转换为UTC存储,并在检索时转换回当前时区。这点需要强调,特别是当系统跨时区使用时,可能会出现时间显示不一致的问题。而datetime不会自动转换时区,这也是两者的区别之一。 然后,默认值和自动更新的特性。用户可能关心如何设置默认值为当前时间,或者在更新时自动更新时间戳。比如,在创建表时,可以指定默认值CURRENT_TIMESTAMP和ON UPDATE CURRENT_TIMESTAMP。需要注意的是,在5.7版本中,每个表只能有一个timestamp列使用这两个属性,但如果有多个timestamp列,可以分别设置默认值或更新时的行为吗?可能需要确认,比如一个列设置DEFAULT CURRENT_TIMESTAMP,另一个设置ON UPDATE,但根据文档,可能仍然有限制。 还要提到,在MySQL 5.6.5之后,允许datetime也使用自动初始化,但用户问的是5.7,所以这个特性是支持的,不过问题集中在timestamp上,是否需要对比datetime?可能用户需要明确两者的区别,所以应该简单提一下。 此外,需要注意timestamp列是否允许NULL。默认情况下,timestamp列是NOT NULL的,如果没有显式声明,并且没有默认值的话,可能会有默认值的问题。例如,如果插入一行时不指定timestamp列的值,第一个timestamp列会被设置为当前时间,后续的则设置为'0000-00-00 00:00:00',但在严格模式下会报错。不过这可能随着版本不同而变化,需要确认5.7的默认行为。 还有,显式设置NULL的情况。如果列允许NULL,且没有默认值,那么插入时可以设为NULL,否则会报错。但默认情况下timestamp列是否允许NULL?根据文档,如果使用explicit_defaults_for_timestamp参数,可能会影响这个行为。在5.7中,默认这个参数是OFF,所以第一个timestamp列如果没有指定NULL属性,会自动设置为NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,而后续的timestamp列会被视为NOT NULL DEFAULT '0000-00-00 00:00:00',但这样的默认值在严格模式下可能不允许。 因此,在严格模式下,可能需要显式地为timestamp列设置默认值或者允许NULL,否则插入时可能出现错误。需要提醒用户注意这一点。 另外,举例说明如何创建表,包含timestamp列,并展示自动初始化和更新的语法。比如: CREATE TABLE example ( id INT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP ); 这里要注意,在5.7中,如果两个列都使用DEFAULT和ON UPDATE可能会有问题,因为旧版本只允许一个列这样设置。但可能从某个版本开始允许了,需要确认。比如在5.6.5之后,这个限制可能被取消,允许每个表有多个timestamp列使用DEFAULT或ON UPDATE,但需要验证。如果用户使用的是5.7,应该没问题,但需要指出可能需要注意的版本差异。 最后,使用时区转换的例子,比如SET time_zone = '+00:00'; 来查看不同时区下的时间显示差异,说明timestamp的时区敏感性。 可能还需要提醒用户2038年的限制,以及如果超出范围会发生什么,比如存储失败或者值被截断。 总结要涵盖的内容点:定义与范围、时区处理、默认值与自动更新、NULL处理、示例和注意事项。确保信息准确,特别是针对5.7版本的特定行为。</think>MySQL 5.7 中的 `TIMESTAMP` 类型用于存储日期和时间,具有一些独特的特性和注意事项。以下是其主要用法和细节: --- ### 1. **定义与范围** - **存储格式**:`TIMESTAMP` 存储为 **UTC 时间**,占用 **4 字节**。 - **时间范围**:`1970-01-01 00:00:01` UTC 至 `2038-01-19 03:14:07` UTC(受 4 字节限制,称为“2038 年问题”)。 - **显示依赖时区**:检索时会根据当前会话的时区设置(通过 `time_zone` 变量)自动转换时间。 --- ### 2. **时区处理** - **存储时自动转 UTC**:插入或更新时间时,MySQL 会将其从当前会话时区转换为 UTC 存储。 - **检索时转回本地时区**:查询时再将 UTC 时间转换回当前会话时区。 示例: ```sql -- 设置会话时区为 UTC+8(东八区) SET time_zone = '+08:00'; INSERT INTO table (ts_column) VALUES ('2023-10-01 12:00:00'); -- 若切换时区为 UTC SET time_zone = '+00:00'; SELECT ts_column FROM table; -- 显示为 '2023-10-01 04:00:00' ``` --- ### 3. **默认值与自动更新** - **默认值**: - 若未显式指定默认值,第一个 `TIMESTAMP` 列默认 `DEFAULT CURRENT_TIMESTAMP`。 - 其他 `TIMESTAMP` 列默认 `DEFAULT '0000-00-00 00:00:00'`(严格模式下可能报错)。 - **自动更新**: - 可通过 `ON UPDATE CURRENT_TIMESTAMP` 在行更新时自动更新时间。 - **MySQL 5.6.5+** 允许同一表多个列使用 `CURRENT_TIMESTAMP`(需显式定义)。 **示例表定义**: ```sql CREATE TABLE example ( id INT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP ); ``` - `created_at` 在插入时自动填充当前时间。 - `updated_at` 在插入或更新时自动更新为当前时间。 --- ### 4. **NULL 值处理** - 默认 `TIMESTAMP` 列为 `NOT NULL`。若未显式赋值且无默认值,会尝试用 `'0000-00-00 00:00:00'` 填充(严格模式下可能报错)。 - 允许 `NULL` 需显式声明: ```sql CREATE TABLE demo ( ts_nullable TIMESTAMP NULL -- 允许插入 NULL ); ``` --- ### 5. **与 `DATETIME` 的区别** | 特性 | TIMESTAMP | DATETIME | |--------------------|-------------------------------|-----------------------| | **存储范围** | 1970-01-01 ~ 2038-01-19 | 1000-01-01 ~ 9999年 | | **时区敏感** | 自动转换 | 按字面值存储 | | **存储空间** | 4 字节 | 8 字节 | | **自动初始化/更新**| 支持(需显式定义) | MySQL 5.6.5+ 支持 | --- ### 6. **注意事项** 1. **2038 年限制**:超出 `2038-01-19 03:14:07` 的时间会溢出,建议未来使用 `DATETIME`。 2. **严格模式**:若启用 SQL 严格模式 (`STRICT_ALL_TABLES`),无效日期或隐式默认值可能导致错误。 3. **时区一致**:跨时区应用需确保会话时区设置正确,避免时间显示混乱。 4. **参数影响**:通过 `explicit_defaults_for_timestamp` 可禁用默认自动初始化行为(需谨慎修改)。 --- ### 7. **操作示例** ```sql -- 插入当前时间 INSERT INTO example (id) VALUES (1); -- created_at 和 updated_at 均为当前时间 -- 更新时自动修改 updated_at UPDATE example SET id = 2 WHERE id = 1; -- updated_at 变为当前时间 -- 显式插入时间 INSERT INTO example (created_at, updated_at) VALUES ('2023-10-01 08:00:00', '2023-10-01 08:00:00'); ``` --- 通过合理利用 `TIMESTAMP` 的时区转换和自动更新特性,可以高效管理记录的创建和修改时间。但在涉及大范围时间或长期系统时,需谨慎评估是否选用 `DATETIME`。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值