2024-03-07 18:15:14
MySQL日期函数使用指南及WHERE查询时间戳转换格式教程
MySQL的日期函数与数据类型选择直接影响查询效率与数据一致性。以下从时间戳转换、日期格式化、WHERE子句优化及跨时区处理四个方面展开说明。
一、时间戳与日期时间的互转日期时间转时间戳
UNIX_TIMESTAMP(date):将日期时间转为Unix时间戳(自1970-01-01 UTC的秒数)。SELECT UNIX_TIMESTAMP('2023-10-26 10:30:00'); -- 返回 1698306600
时间戳转日期时间
FROM_UNIXTIME(unix_timestamp[, format]):将时间戳转为日期时间,可指定格式。SELECT FROM_UNIXTIME(1698306600); -- 返回 '2023-10-26 10:30:00'SELECT FROM_UNIXTIME(1698306600, '%Y年%m月%d日 %H:%i:%s'); -- 返回 '2023年10月26日 10:30:00'
日期格式化为字符串
DATE_FORMAT(date, format):灵活格式化日期为字符串。SELECT DATE_FORMAT('2023-10-26 10:30:00', '%Y/%m/%d %H:%i'); -- 返回 '2023/10/26 10:30'
字符串解析为日期
STR_TO_DATE(string, format):将字符串按指定格式转为日期类型。SELECT STR_TO_DATE('26-10-2023 10:30:00', '%d-%m-%Y %H:%i:%s'); -- 返回 '2023-10-26 10:30:00'
避免对列使用函数
错误示例:在列上直接使用函数会导致索引失效,引发全表扫描。SELECT * FROM orders WHERE DATE(order_time) = '2023-10-26'; -- 低效SELECT * FROM orders WHERE FROM_UNIXTIME(timestamp_column, '%Y-%m-%d') = '2023-10-26'; -- 低效
高效写法
DATETIME/DATE类型:使用范围查询,直接比较列值。SELECT * FROM your_table WHERE your_datetime_column >= '2023-10-26 00:00:00' AND your_datetime_column < '2023-10-27 00:00:00'; -- 高效
时间戳类型:将比较值转为时间戳或直接使用数值比较。SELECT * FROM your_table WHERE timestamp_column >= UNIX_TIMESTAMP('2023-10-26 00:00:00') AND timestamp_column < UNIX_TIMESTAMP('2023-10-27 00:00:00'); -- 高效SELECT * FROM your_table WHERE timestamp_column >= 1698307200 AND timestamp_column < 1698393600; -- 更高效
性能影响说明
在WHERE子句列上使用函数会强制MySQL逐行计算,无法利用索引,导致性能下降。例如,对百万级数据表的全表扫描可能耗时数秒甚至分钟,而索引查询仅需毫秒级。
数据类型选择
DATE:仅存储日期(如生日),占3字节。
DATETIME:存储绝对时间(如订单时间),范围广(1000-01-01至9999-12-31),占8字节,不受时区影响。
TIMESTAMP:存储时区敏感时间,范围窄(1970-2038年),占4字节,自动转换时区,适合记录事件时间。
推荐场景:
仅需日期 → DATE
需绝对时间且无时区需求 → DATETIME
需自动时区转换或自动更新 → TIMESTAMP(需注意2038年问题)
跨时区处理策略
统一存储UTC时间:写入时将用户时间转为UTC存储,读取时转回用户时区。
优点:数据统一无歧义,避免时区混乱。
实现示例:-- 写入时转换(应用层处理)INSERT INTO events (event_time) VALUES (UTC_TIMESTAMP);-- 读取时转换(应用层处理)SELECT FROM_UNIXTIME(UNIX_TIMESTAMP(event_time) + 3600*8, '%Y-%m-%d %H:%i:%s') FROM events; -- 转为东八区