- 关于 TiDB
- 快速上手
- 部署集群
- 数据迁移
- 数据迁移概述
- 从 MySQL 迁移至 TiDB
- 从 CSV 文件迁移至 TiDB
- 运维操作
- 监控与告警
- 故障诊断
- 性能调优
- 系统调优
- 软件调优
- SQL 性能调优
- 教程
- TiDB 生态工具
- TiDB 生态工具功能概览
- TiDB 生态工具适用场景
- TiDB 工具下载
- Backup & Restore (BR)
- TiDB Binlog
- TiDB Lightning
- TiCDC 简介
- Dumpling 使用文档
- sync-diff-inspector
- Loader 使用文档
- Mydumper 使用文档
- Syncer 使用文档
- TiSpark
- 参考指南
- 架构
- 监控指标
- 安全加固
- 权限
- SQL
- SQL 语言结构和语法
- 属性
- 字面值
- Schema 对象名
- 关键字
- 用户自定义变量
- 表达式语法
- 注释语法
- SQL 语句
- ADD COLUMN
- ADD INDEX
- ADMIN
- ALTER DATABASE
- ALTER INSTANCE
- ALTER TABLE
- ALTER USER
- ANALYZE
- BACKUP
- BEGIN
- CHANGE COLUMN
- CHANGE DRAINER
- CHANGE PUMP
- COMMIT
- CREATE [GLOBAL|SESSION] BINDING
- CREATE DATABASE
- CREATE INDEX
- CREATE ROLE
- CREATE SEQUENCE
- CREATE TABLE LIKE
- CREATE TABLE
- CREATE USER
- CREATE VIEW
- DEALLOCATE
- DELETE
- DESC
- DESCRIBE
- DO
- DROP [GLOBAL|SESSION] BINDING
- DROP COLUMN
- DROP DATABASE
- DROP INDEX
- DROP ROLE
- DROP SEQUENCE
- DROP STATS
- DROP TABLE
- DROP USER
- DROP VIEW
- EXECUTE
- EXPLAIN ANALYZE
- EXPLAIN
- FLASHBACK TABLE
- FLUSH PRIVILEGES
- FLUSH STATUS
- FLUSH TABLES
- GRANT
- GRANT
- INSERT
- KILL [TIDB]
- LOAD STATS
- MODIFY COLUMN
- PREPARE
- RECOVER TABLE
- RENAME INDEX
- RENAME TABLE
- REPLACE
- RESTORE
- REVOKE
- REVOKE
- ROLLBACK
- SELECT
- SET DEFAULT ROLE
- SET [NAMES|CHARACTER SET]
- SET PASSWORD
- SET ROLE
- SET TRANSACTION
- SET [GLOBAL|SESSION]
- SHOW [BACKUPS|RESTORES]
- SHOW ANALYZE STATUS
- SHOW [GLOBAL|SESSION] BINDINGS
- SHOW BUILTINS
- SHOW CHARACTER SET
- SHOW COLLATION
- SHOW [FULL] COLUMNS FROM
- SHOW CONFIG
- SHOW CREATE SEQUENCE
- SHOW CREATE TABLE
- SHOW CREATE USER
- SHOW DATABASES
- SHOW DRAINER STATUS
- SHOW ENGINES
- SHOW ERRORS
- SHOW [FULL] FIELDS FROM
- SHOW GRANTS
- SHOW INDEX [FROM|IN]
- SHOW INDEXES [FROM|IN]
- SHOW KEYS [FROM|IN]
- SHOW MASTER STATUS
- SHOW PLUGINS
- SHOW PRIVILEGES
- SHOW [FULL] PROCESSLIST
- SHOW PROFILES
- SHOW PUMP STATUS
- SHOW SCHEMAS
- SHOW STATS_HEALTHY
- SHOW STATS_HISTOGRAMS
- SHOW STATS_META
- SHOW [GLOBAL|SESSION] STATUS
- SHOW TABLE NEXTROWID
- SHOW TABLE REGIONS
- SHOW TABLE STATUS
- SHOW [FULL] TABLES
- SHOW [GLOBAL|SESSION] VARIABLES
- SHOW WARNINGS
- SHUTDOWN
- Split Region 使用文档
- START TRANSACTION
- TRACE
- TRUNCATE
- UPDATE
- USE
- 数据类型
- 函数与操作符
- 约束
- 生成列
- SQL 模式
- 事务
- 垃圾回收 (GC)
- 视图
- 分区表
- 字符集和排序规则
- 系统表
- TiDB 系统表
- INFORMATION_SCHEMA
- TiDB 简介
- ANALYZE_STATUS
- CHARACTER_SETS
- CLUSTER_CONFIG
- CLUSTER_HARDWARE
- CLUSTER_INFO
- CLUSTER_LOAD
- CLUSTER_LOG
- CLUSTER_SYSTEMINFO
- COLLATIONS
- COLLATIONCHARACTERSET_APPLICABILITY
- COLUMNS
- DDL_JOBS
- ENGINES
- INSPECTION_RESULT
- INSPECTION_RULES
- INSPECTION_SUMMARY
- KEYCOLUMNUSAGE
- METRICS_SUMMARY
- METRICS_TABLES
- PARTITIONS
- PROCESSLIST
- SCHEMATA
- SEQUENCES
- SESSION_VARIABLES
- SLOW_QUERY
- STATISTICS
- TABLES
- TABLE_CONSTRAINTS
- TABLESTORAGESTATS
- TIDBHOTREGIONS
- TIDB_INDEXES
- TIDBSERVERSINFO
- TIFLASH_REPLICA
- TIKVREGIONPEERS
- TIKVREGIONSTATUS
- TIKVSTORESTATUS
- USER_PRIVILEGES
- VIEWS
- Metrics Schema
- SQL 语言结构和语法
- UI
- CLI
- 命令行参数
- 配置文件参数
- 系统变量
- 存储引擎
- TiUP
- 遥测
- 错误码与故障诊断
- TiCDC Open Protocol
- 通过拓扑 label 进行副本调度
- 常见问题解答 (FAQ)
- 术语表
日期和时间类型
TiDB 支持 MySQL 所有的日期和时间类型,包括 、、、 以及 。完整信息可以参考 MySQL 中的时间和日期类型。
每种类型都有有效值范围,值为 0 表示无效值。此外,TIMESTAMP
和 DATETIME
类型能自动生成新的时间值。
关于日期和时间值类型,需要注意:
日期部分必须是“年-月-日”的格式(例如
1998-09-04
),而不是“月-日-年”或“日-月-年”的格式。如果日期的年份部分是 2 位数,TiDB 会根据类型定义
DATE
类型DATE
类型只包含日期部分,不包含时间部分。DATE
类型的格式为YYYY-MM-DD
,支持的范围是1000-01-01
到9999-12-31
。DATE
TIME
类型TIME
类型的格式为HH:MM:SS[.fraction]
,支持的范围是-838:59:59.000000
到838:59:59.000000
。TIME
不仅可用于指示一天内的时间,还可用于指两个事件之间的时间间隔。fsp
参数表示秒精度,取值范围为:0 ~ 6,默认值为 0。TIME[(fsp)]
注意:
注意
TIME
的缩写形式。例如,11:12
表示11:12:00
而不是00:11:12
。但是,1112
表示00:11:12
。这些差异取决于:
字符的存在与否。DATETIME
类型DATETIME
类型是日期和时间的组合,格式为YYYY-MM-DD HH:MM:SS[.fraction]
。支持的范围是1000-01-01 00:00:00.000000
到9999-12-31 23:59:59.999999
。fsp
参数表示秒精度,取值范围为 0~6,默认值为 0。TiDB 支持字符串或数字转换为DATETIME
类型。DATETIME[(fsp)]
TIMESTAMP
类型TIMESTAMP
类型是日期和时间的组合,支持的范围是 UTC 时间从1970-01-01 00:00:01.000000
到2038-01-19 03:14:07.999999
。fsp
参数表示秒精度,取值范围为 0~6,默认值为 0。在TIMESTAMP
中,不允许零出现在月份部分或日期部分,唯一的例外是零值本身0000-00-00 00:00:00
。TIMESTAMP[(fsp)]
时区处理
当存储
TIMESTAMP
时,TiDB 会将当前时区的TIMESTAMP
值转换为 UTC 时区。当读取TIMESTAMP
时,TiDB 将存储的TIMESTAMP
值从 UTC 时区转换为当前时区(注意:DATETIME
不会这样处理)。每次连接的默认时区是服务器的本地时区,可以通过环境变量time_zone
进行修改。警告:
和 MySQL 一样,
TIMESTAMP
数据类型受 2038 年问题的影响。如果存储的值大于 2038,建议使用DATETIME
类型。YEAR
类型YEAR
类型的格式为YYYY
,支持的值范围是1901
到2155
,也支持零值0000
。YEAR[(4)]
YEAR
类型遵循以下格式规则:- 如果是四位数的数值,支持的范围是
1901
至2155
。 - 如果是四位数的字符串,支持的范围是
'1901'
到'2155'
。 - 如果是 1~99 之间的一位数或两位数的数字,1~69 换算成 2001~2069,70~99 换算成 1970~1999。
- 支持
'0'
到'99'
之间的一位数或两位数字符串的范围 - 将数值
0
转换为0000
,将字符串'0'
或'00'
转换为'2000'
。
无效的
YEAR
值会自动转换为0000
(如果用户没有使用NO_ZERO_DATE
SQL 模式)。自动初始化和更新
TIMESTAMP
或DATETIME
带有
TIMESTAMP
或DATETIME
数据类型的列可以自动初始化为或更新为当前时间。对于表中任何带有
TIMESTAMP
或DATETIME
数据类型的列,你可以设置默认值,或自动更新为当前时间戳。在定义列的时候,
TIMESTAMP
和DATETIME
可以通过DEFAULT CURRENT_TIMESTAMP
和ON UPDATE CURRENT_TIMESTAMP
来设置。DEFAULT
也可以设置为一个特定的值,例如DEFAULT 0
或DEFAULT '2000-01-01 00:00:00'
。CREATE TABLE t1 ( ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, dt DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP );
除非指定
DATETIME
的值为NOT NULL
,否则默认DATETIME
的值为NULL
。指定DATETIME
的值为NOT NULL
时,如果没有设置默认值,则默认值为0
。CREATE TABLE t1 ( dt1 DATETIME ON UPDATE CURRENT_TIMESTAMP, -- default NULL dt2 DATETIME NOT NULL ON UPDATE CURRENT_TIMESTAMP -- default 0 );
时间值的小数部分
DATETIME
和TIMESTAMP
值最多可以有 6 位小数,精确到毫秒。如果包含小数部分,值的格式为YYYY-MM-DD HH:MM:SS[.fraction]
,小数部分的范围为000000
到999999
。必须使用小数点分隔小数部分与其他部分。使用
type_name(fsp)
可以定义精确到小数的列,其中type_name
可以是TIME
、DATETIME
或TIMESTAMP
。例如:CREATE TABLE t1 (t TIME(3), dt DATETIME(6));
fsp
范围是0
到6
。0
表示没有小数部分。如果省略了fsp
,默认为0
。当插入包含小数部分的
TIME
、DATETIME
或TIMESTAMP
时,如果小数部分的位数过少或过多,可能需要进行四舍五入。例如:CREATE TABLE fractest( c1 TIME(2), c2 DATETIME(2), c3 TIMESTAMP(2) );
Query OK, 0 rows affected (0.33 sec)
INSERT INTO fractest VALUES > ('17:51:04.777', '2014-09-08 17:51:04.777', '2014-09-08 17:51:04.777');
Query OK, 1 row affected (0.03 sec)
SELECT * FROM fractest;
+-------------|------------------------|------------------------+ | c1 | c2 | c3 | +-------------|------------------------|------------------------+ | 17:51:04.78 | 2014-09-08 17:51:04.78 | 2014-09-08 17:51:04.78 | +-------------|------------------------|------------------------+ 1 row in set (0.00 sec)
日期和时间类型的转换
在日期和时间类型之间进行转换时,有些转换可能会导致信息丢失。例如,
DATE
、DATETIME
和TIMESTAMP
都有各自的有效值范围。TIMESTAMP
不能早于 UTC 时间的 1970 年,也不能晚于 UTC 时间的2038-01-19 03:14:07
。根据这个规则,1968-01-01
对于DATE
或DATETIME
是有效的,但当1968-01-01
转换为TIMESTAMP
时,就会变成 0。DATE
的转换:- 当
DATE
转换为DATETIME
或TIMESTAMP
时,会添加时间部分00:00:00
,因为DATE
不包含任何时间信息。 - 当
DATE
转换为TIME
时,结果是00:00:00
。
DATETIME
或TIMESTAMP
的转换:- 当
DATETIME
或TIMESTAMP
转换为DATE
时,时间和小数部分将被舍弃。例如,1999-12-31 23:59:59.499
被转换为1999-12-31
。 - 当
DATETIME
或TIMESTAMP
转换为TIME
时,时间部分被舍弃,因为TIME
不包含任何时间信息。
如果要将
TIME
转换为其他时间和日期格式,日期部分会自动指定为CURRENT_DATE()
。最终的转换结果是由TIME
和CURRENT_DATE()
组成的日期。也就是说,如果TIME
的值超出了00:00:00
到23:59:59
的范围,那么转换后的日期部分并不表示当前的日期。当
TIME
转换为DATE
时,转换过程类似,时间部分被舍弃。使用
CAST()
函数可以显式地将值转换为DATE
类型。例如:date_col = CAST(datetime_col AS DATE)
将
TIME
和DATETIME
转换为数字格式。例如:SELECT CURTIME(), CURTIME()+0, CURTIME(3)+0;
+-----------|-------------|--------------+ | CURTIME() | CURTIME()+0 | CURTIME(3)+0 | +-----------|-------------|--------------+ | 09:28:00 | 92800 | 92800.887 | +-----------|-------------|--------------+
SELECT NOW(), NOW()+0, NOW(3)+0;
+---------------------|----------------|--------------------+ | NOW() | NOW()+0 | NOW(3)+0 | +---------------------|----------------|--------------------+ | 2012-08-15 09:28:00 | 20120815092800 | 20120815092800.889 | +---------------------|----------------|--------------------+
年份为两位数
如果日期中包含年份为两位数,这个年份是有歧义的,并不显式地表示实际年份。
对于
DATETIME
、DATE
和TIMESTAMP
类型,TiDB 使用如下规则来消除歧义。- 将 01 至 69 之间的值转换为 2001 至 2069 之间的值。
- 将 70 至 99 之间的值转化为 1970 至 1999 之间的值。
上述规则也适用于
YEAR
类型,但有一个例外。将数字00
插入到YEAR(4)
中时,结果是 0000 而不是 2000。如果想让结果是 2000,需要指定值为
2000
。对于
MIN()
和MAX()
等函数,年份为两位数时可能会得到错误的计算结果。建议年份为四位数时使用这类函数。- 如果是四位数的数值,支持的范围是
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论