MySQL 时区与 serverTimezone

TL;DR 手动为 MySQL 指定非偏移量的时区,以避免 TIMESTAMP 类型夏令时问题和时区转化性能瓶颈 TIMESTAMP 范围:‘1970-01-01 00:00:01’ UTC to ‘2038-01-19 03:14:07’ 连接 MySQL 数据库时,serverTimezone 参数用于指定数据库服务器的时区,需要设置为与 MySQL 服务端相同的时区 MySQL 时区设置影响 TIMESTAMP 类型数据和部分时间函数 MySQL 会话时区设置会影响 TIMESTAMP 和 时间函数(NOW()、CURDATE()、CURTIME()、CURRENT_TIMESTAMP()) 存储 TIMESTAMP 类型数据时,MySQL 会根据当前会话的时区将时间转换为 UTC 时间,MySQL 实际存储的是 UTC 时间。检索时 MySQL 根据会话的时区将存储的 UTC 时间转换为会话对应时区的时间。而 DATETIME 类型的字段存储的时间值是原始值,不受时区影响 MySQL 默认使用 SYSTEM 时区(即操作系统的时区),每个需要时区计算的 MySQL 函数调用都会调用系统库来确定当前系统时区。此调用可能受到全局互斥体的保护,从而导致争用,建议显式设置时区 查询当前时区 # time_zone:MySQL 使用 SYSTEM 的时区 # system_time_zone:SYSTEM 为 CST 时区 show variables like "%time_zone%"; +------------------+--------+ | Variable_name | Value | +------------------+--------+ | system_time_zone | CST | | time_zone | SYSTEM | +------------------+--------+ 不同会话时区对 时间函数 的影响 # 当前时区 # 查看当前的全球和会话时区值 SELECT @@GLOBAL.time_zone, @@SESSION.time_zone; SELECT NOW(), CURDATE(), CURTIME(), CURRENT_TIMESTAMP(); set time_zone = 'America/New_York'; SELECT NOW(), CURDATE(), CURTIME(), CURRENT_TIMESTAMP(); 不同会话时区对 TIMESTAMP 类型的影响 # UTC +8 set time_zone = 'Asia/Shanghai'; CREATE TABLE events ( id INT AUTO_INCREMENT PRIMARY KEY, event_name VARCHAR(255) NOT NULL, event_timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP, event_datetime DATETIME DEFAULT CURRENT_TIMESTAMP ); INSERT INTO events (event_name, event_timestamp, event_datetime) VALUES ('10.24 15:45:00', '2022-10-24 15:45:00', '2022-10-24 15:45:00'); INSERT INTO events (event_name, event_timestamp, event_datetime) VALUES ('12.24 15:45:00', '2022-12-24 15:45:00', '2022-12-24 15:45:00'); SELECT * FROM events; +----+----------------+---------------------+---------------------+ | id | event_name | event_timestamp | event_datetime | +----+----------------+---------------------+---------------------+ | 1 | 10.24 15:45:00 | 2022-10-24 15:45:00 | 2022-10-24 15:45:00 | | 2 | 12.24 15:45:00 | 2022-12-24 15:45:00 | 2022-12-24 15:45:00 | +----+----------------+---------------------+---------------------+ 2 rows in set (0.00 sec) # 仅修改当前会话的时区 set time_zone = 'America/New_York'; SELECT * FROM events; +----+----------------+---------------------+---------------------+ | id | event_name | event_timestamp | event_datetime | +----+----------------+---------------------+---------------------+ | 1 | 10.24 15:45:00 | 2022-10-24 03:45:00 | 2022-10-24 15:45:00 | <- 夏令时,相差 12 小时 | 2 | 12.24 15:45:00 | 2022-12-24 02:45:00 | 2022-12-24 15:45:00 | <- 平时相差 13 小时 +----+----------------+---------------------+---------------------+ 2 rows in set (0.00 sec) 纽约 UTC 时差通常为 UTC-5(EST),夏令时为 UTC-4(EDT),所以将原本的会话从上海(UTC+8) 转到纽约时,TIMESTAMP 相差了 13 或 12(夏令时) 小时,所以为了自动转换夏令时,指定时区最好使用时区名词 Asia/Shanghai,避免使用偏移量:'+08:00' ...

December 19, 2024

Oracle数据库对比MySQL

基本 Oracle默认端口:1521 默认用户:system MySQL默认端口:3306 默认用户:root 连接MySQL: mysql -u root -p -- 输入密码 -- 查询所有数据库 show databases; -- 切换到 "test" 这个数据库 use test; -- 查询该数据库所有表 show tables; 连接Oracle: sqlplus -- 输入用户名 -- 输入密码 -- 查询该用户的表 select TABLE_NAME from user_tables; 注意:Oracle 登录需要授予登录用户 session权限,建表需要分配限额 常用字段类型 Oracle 数值 number number(10) number(10,2) 字符串 varchar2 varchar2(20) 日期 date MySQL 数值 tinyint smallint mediumint int bigint decimal 字符串 varchar(10) 必须指定 日期 date time datetime timestamp year ...

February 3, 2021