mysql timestamp 基本用法

本文详细解析了数据库中timestamp列的特点及应用。介绍了timestamp列可以存储的时间范围、精度以及不同显示尺寸的格式。此外还讨论了如何利用timestamp列进行自动日期时间标记,并提供了验证示例。

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

timestamp列类型
timestamp值可以从1970的某时的开始一直到2037年,精度为一秒,其值作为数字显示。
timestamp值显示尺寸的格式如下表所示:

+---------------+----------------+
| 列类型        | 显示格式       |
| timestamp(14) | yyyymmddhhmmss | 
| timestamp(12) | yymmddhhmmss   |
| timestamp(10) | yymmddhhmm     |
| timestamp(8)  | yyyymmdd       |
| timestamp(6)  | yymmdd         |
| timestamp(4)  | yymm           |
| timestamp(2)  | yy             |
+---------------+----------------+
“完整”timestamp格式是14位,但timestamp列也可以用更短的显示尺寸创造
最常见的显示尺寸是6、8、12、和14。
你可以在创建表时指定一个任意的显示尺寸,但是定义列长为0或比14大均会被强制定义为列长14。
列长在从1~13范围的奇数值尺寸均被强制为下一个更大的偶数。

列如:
定义字段长度     强制字段长度
timestamp(0) ->  timestamp(14)
timestamp(15)->  timestamp(14)
timestamp(1) ->  timestamp(2)
timestamp(5) ->  timestamp(6)


所有的timestamp列都有同样的存储大小,
使用被指定的时期时间值的完整精度(14位)存储合法的值不考虑显示尺寸。
不合法的日期,将会被强制为0存储
这有几个含意:
    1、虽然你建表时定义了列timestamp(8),但在你进行数据插入与更新时timestamp列
           实际上保存了14位的数据(包括年月日时分秒),
           只不过在你进行查询时mysql返回给你的是8位的年月日数据。
           如果你使用alter table拓宽一个狭窄的timestamp列,以前被“隐蔽”的信息将被显示。
    2、同样,缩小一个timestamp列不会导致信息失去,除了感觉上值在显示时,较少的信息被显示出。
    3、尽管timestamp值被存储为完整精度,直接操作存储值的唯一函数是unix_timestamp();
           由于mysql返回timestamp列的列值是进过格式化后的检索的值,
           这意味着你可能不能使用某些函数来操作timestamp列(例如hour()或second()),
           除非timestamp值的相关部分被包含在格式化的值中。
           例如,一个timestamp列只有被定义为timestamp(10)以上时,timestamp列的hh部分才会被显示,
           因此在更短的timestamp值上使用hour()会产生一个不可预知的结果。
    4、不合法timestamp值被变换到适当类型的“零”值(00000000000000)。(datetime,date亦然)       


你可以使用下列语句来验证:
create table test ('id' int (3) unsigned auto_increment, 'date1' timestamp (8) primary key('id'));
insert into test set id = 1;
select * from test;
+----+----------------+
| id | date1          |
+----+----------------+
|  1 | 20021114       |
+----+----------------+
alter table test change 'date1' 'date1' timestamp(14);
select * from test;
+----+----------------+
| id | date1          |
+----+----------------+
|  1 | 20021114093723 |
+----+----------------+


 


你可以使用timestamp列类型自动地用当前的日期和时间标记insert或update的操作。
如果你有多个timestamp列,只有第一个自动更新。
自动更新第一个timestamp列在下列任何条件下发生:


   1、列值没有明确地在一个insert或load data infile语句中指定。
   2、列值没有明确地在一个update语句中指定且另外一些的列改变值。
       (注意一个update设置一个列为它已经有的值,
        这将不引起timestamp列被更新,
        因为如果你设置一个列为它当前的值,mysql为了效率而忽略更改。)
   3、你明确地设定timestamp列为null.
   4、除第一个以外的timestamp列也可以设置到当前的日期和时间,只要将列设为null,或now()。



create table test (
     'id' int (3) unsigned auto_increment,
     'date1' timestamp (14),
     'date2' timestamp (14),
      primary key('id')
      );


insert into test (id, date1, date2) values (1, null, null);
insert into test set id= 2;
+----+----------------+----------------+
| id | date1          | date2          |
+----+----------------+----------------+
|  1 | 20021114093723 | 20021114093723 |
|  2 | 20021114093724 | 00000000000000 |
+----+----------------+----------------+
->第一条指令因设date1、date2为null,所以date1、date2值均为当前时间
  第二条指令因没有设date1、date2列值,第一个timestamp列date1为更新为当前时间,
    而二个timestamp列date2因日期不合法而变为“00000000000000”



update test set id= 3 where id=1;

<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、付费专栏及课程。

余额充值