MySQL中的数据类型之日期/时间类型

MySQL中的数据类型主要有:数字类型、日期/时间类型、字符串类型。

日期/时间类型

MySQL中的日期和时间类型有datetimedatetimetimestampyear。每一种时间类型都有一定范围的有效值,也有零值,当你指定一个无效的MySQL表示不了的值的时候,MySQL可能会使用零值。其中timestamp类型和datetime类型可以自动更新。

MySQL允许timedatetimetimestamp类型的值有小数秒,最多到微秒精度。定一个列包含小数秒部分,使用语法type_name(fsp),其中type_name可以是timedatetimetimestampfsp是小数秒的精度,例如:

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列,可以通过使用defaulton 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一样。

注意
timestampdatetime最大的区别是: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从零开始学》 刘增杰 李坤 著

你可能感兴趣的:(数据库)