MySQL中的数据类型主要有:数字类型、日期/时间类型、字符串类型。
日期/时间类型
MySQL中的日期和时间类型有date
、time
、datetime
、timestamp
和year
。每一种时间类型都有一定范围的有效值,也有零值,当你指定一个无效的MySQL表示不了的值的时候,MySQL可能会使用零值。其中timestamp
类型和datetime
类型可以自动更新。
MySQL允许time
、datetime
、timestamp
类型的值有小数秒,最多到微秒精度。定一个列包含小数秒部分,使用语法type_name(fsp),其中type_name可以是time
、datetime
、timestamp
,fsp是小数秒的精度,例如:
mysql> create table t_fsp (t time(3),dt datetime(6));
Query OK, 0 rows affected (0.02 sec)
mysql> desc t_fsp;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| t | time(3) | YES | | NULL | |
| dt | datetime(6) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
mysql> insert into t_fsp values(now(),now());
Query OK, 1 row affected (0.01 sec)
#t列有3位小数,dt列有6位小数
mysql> select * from t_fsp;
+--------------+----------------------------+
| t | dt |
+--------------+----------------------------+
| 19:45:04.000 | 2018-11-01 19:45:04.000000 |
+--------------+----------------------------+
1 row in set (0.00 sec)
fsp的值,如果指定的话,必须在0~6范围内,0表示没有小数秒,如果不指定fsp,默认为0。
- date
日期类型,支持的范围是’1000-01-01’~‘9999-12-31’。MySQL用’YYYY-MM-DD’的格式显示date
类型,但是允许使用字符串或数字向date
类型的列赋值。如:
mysql> create table t_date(d date);
Query OK, 0 rows affected (0.02 sec)
#使用字符串'20181101'和数字20181102都可以插入成功
#并且由于MySQL允许不太严格的语法,使得任意标点都可以
#用作日期各部分之间的分割符,下面的'-','@','/'都可以。
mysql> insert into t_date values('20181101'),(20181102),('2018-11-03'),('2018@11@21'),('2018/11/22');
Query OK, 5 rows affected (0.00 sec)
Records: 5 Duplicates: 0 Warnings: 0
mysql> select * from t_date;
+------------+
| d |
+------------+
| 2018-11-01 |
| 2018-11-02 |
| 2018-11-03 |
| 2018-11-21 |
| 2018-11-22 |
+------------+
5 rows in set (0.00 sec)
- datetime [(fsp)]
日期(date)和时间(time)的组合类型。支持的范围是: ‘1000-01-01 00:00:00.000000’\~’9999-12-31 23:59:59.999999’。MySQL用’YYYY-MM-DD HH:MM:SS[.fraction]’ 这样的格式显示datetime
类型的值(fraction表示小数部分),但是也允许用字符串或数字向datetime
类型的列赋值。例如:
mysql> create table t_datetime(dt datetime);
Query OK, 0 rows affected (0.02 sec)
mysql> desc t_datetime;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| dt | datetime | YES | | NULL | |
+-------+----------+------+-----+---------+-------+
1 row in set (0.01 sec)
#注意,下面两个值一个是字符串,一个是数字都可以插入表中。
mysql> insert into t_datetime values('20181101200211'),(20181101200213);
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> select * from t_datetime;
+---------------------+
| dt |
+---------------------+
| 2018-11-01 20:02:11 |
| 2018-11-01 20:02:13 |
+---------------------+
2 rows in set (0.00 sec)
对于datetime
列,可以通过使用default
和on update
来自动初始化和更新到当前时间,例如:
mysql> create table t1(id int,
-> dt_1 datetime default current_timestamp,
-> dt_2 datetime default current_timestamp on update current_timestamp);
Query OK, 0 rows affected (0.01 sec)
mysql> insert into t1(id) values(1),(2);
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0
#可以看到dt_1、dt_2列都有当前时间作为默认值,因为设置了default current_timestamp
mysql> select * from t1;
+------+---------------------+---------------------+
| id | dt_1 | dt_2 |
+------+---------------------+---------------------+
| 1 | 2018-11-01 20:13:12 | 2018-11-01 20:13:12 |
| 2 | 2018-11-01 20:13:12 | 2018-11-01 20:13:12 |
+------+---------------------+---------------------+
2 rows in set (0.00 sec)
mysql> update t1 set id = 11 where id =1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
#可以看到id=11的这一行因为更新了id,dt_2列也跟着更新了时间,因为dt_2列定义
#的时候设置了on update
mysql> select * from t1;
+------+---------------------+---------------------+
| id | dt_1 | dt_2 |
+------+---------------------+---------------------+
| 11 | 2018-11-01 20:13:12 | 2018-11-01 20:13:35 |
| 2 | 2018-11-01 20:13:12 | 2018-11-01 20:13:12 |
+------+---------------------+---------------------+
2 rows in set (0.00 sec)
- timestamp [(fsp)]
时间戳类型,表示的范围为:‘1970-01-01 00:00:01.000000’ UTC 到 ‘2038-01-19 03:14:07.999999’ UTC。 时间戳的值存储的时候是存储从’1970-01-01 00:00:00’ UTC纪元开始的秒数。一个时间戳不能表示’1970-01-01 00:00:00’因为它等于距离纪元0秒,然而0被用来表示’0000-00-00 00:00:00’,即时间戳类型的零值。
fsp和datetime的含义一样。自动初始化和自动更新的定义也和datetime一样。
注意
:timestamp
和datetime
最大的区别是:datetime
在存储日期数据时,按实际输入的格式存储,即输入什么就存储什么,与时区无关;而timestamp
值的存储是以UTC(世界标准时间)格式保存的,存储时对当前时区进行转换,检索时再转换回当前时区,即查询时,根据当前时区的不同,显示的时间值是不同的。
日期/时间类型所占空间
数据类型 | MySQL 5.6.4版本之前所需空间 | MySQL 5.6.4及以后版本所需空间 |
year | 1 字节 | 1 字节 |
date | 3 字节 | 3 字节 |
time | 3 字节 | 3 字节 + 小数秒存储空间 |
datetime | 8 字节 | 5 字节 + 小数秒存储空间 |
timestamp | 4 字节 | 4 字节 + 小数秒存储空间 |
参考资料:
1.https://dev.mysql.com/doc/refman/8.0/en/storage-requirements.html 2.《MySQL5.6从零开始学》 刘增杰 李坤 著