一、前言
在前面的MySQL学习中我们学习了数据库的基本操作,本期我们将学习有关MySQL中的数据类型知识。
MySQL支持多种数据类型,主要有数值类型、日期/时间类型和字符串类型。
二、我的环境
- 电脑系统:Windows 11
- 数据库管理系统版本:MySQL 8
- 数据库管理工具:Nacicat Premium 16
三、整数类型
数值型数据类型主要用于存储数字,MySQL提供的整数类型有TINYINT、SMALLINT、MEDIUMINT、INT(INTEGER)、BIGINT。整数类型的属性字段可以添加AUTO_INCREMENT自增约束条件。
类型名称 | 说明 | 存储要求 |
TINYINT | 很小的整数 | 1字节 |
SMALLINT | 小的整数 | 2字节 |
MEDIUMINT | 中等大小的整数 | 3字节 |
INT(INTEGER) | 普通大小的整数 | 4字节 |
BIGINT | 大整数 | 8字节 |
从表中可以看出不同的类型整数存储所需的字节数是不同的,相应的占用字节越多的类型所能表示的数值范围越大。
举个例子,我们创建一个表tmp1,其中字段x、y、z、m、n数据类型依次为TINYINT、SMALLINT、MEDIUMINT、INT、BIGINT。
CREATETABLE tmp1 ( x TINYINT, y SMALLINT, z MEDIUMINT, m INT, n BIGINT);
然后我们查看一下表结构:
不同的整数类型有不同的取值范围,并且需要不同的存储空间,因此应该根据实际需要选择最合适的类型,这样有利于提高查询的效率和节省存储空间。
四、浮点数类型和定点数类型
浮点数类型有两种:单精度浮点数类型(FLOAT)和双精度浮点类型(DOUBLE),定点数只有一种DECIMAL。
浮点数类型和定点数类型都可以用(M,N)来表示,其中M是精度,表示总共的位数,N是标度,表示小数的位数。
定点数类型不同于浮点数类型,定点数实际是以串存放的,可能的最大取值范围与DOUBLE一样,但是其有效的取值范围由M和D的值决定。
举个例子:创建表tmp2,其中字段x,y,z的数据类型依次为FLOAT(5,1)、DOUBLE(5,1)和DECIMAL(5,1),向表中插入数据5.12、5.15和5.123。
CREATETABLE tmp2(x FLOAT(5,1), y DOUBLE(5,1), z DECIMAL(5,1));
向表中插入数据:
INSERTINTO tmp2 VALUES(5.12,5.15,5.123);
插入数据的时候报警告信息, 我们查看一下警告信息:
SHOW WARNINGS;Data truncated for column 'z' at row 1
可以看出z读者数值被截断了,我们查看一下表tmp2:
SELECT*FROM tmp2;
FLOAT和DOUBLE在不指定精度时,默认会按照实际精度,而DECIMAL若不指定精度则默认是(10,0)。
一般来说,在对精度要求比较高的时候使用DECIMAL类型比较好,另外两个浮点数进行减法和比较运算时容易出问题,所以在使用浮点数时需要注意尽量避免做浮点数比较。
五、日期和时间类型
MySQL中由多种表示日期的数据类型,主要有DATETIME、DATE、TIMESTAMP、TIME和YEAR。
类型名称 | 日期格式 | 日期范围 | 存储需求 |
YEAR | YYYY | 1901~2155 | 1字节 |
TIME | HH:MM:SS | -838:59:59~838:59:59 | 3字节 |
DATE | YYYY-MM-DD | 1000-01-01~9999-12-3 | 3字节 |
DATETIME | YYYY-MM-DD HH:MM:SS | 1000-01-01 00:00:00~9999-12-31 23:59:59 | 8字节 |
TIMESTAMP | YYYY-MM-DD HH:MM:SS | 1970-01-01 00:00:01 UTC~2038-01-19 03:14:07 UTC | 4字节 |
1、YEAR
YEAR类型时一个单字节类型,用于表示年。
举个例子:
创建一个数据表tmp3,定义字段y的数据类型为YEAR,向表中插入值2010、2166。
CREATETABLE tmp3(y YEAR);
向表中插入数据:
INSERTINTO tmp3 VALUES(2010),('2010');
在插入2160时报错,这是因为2160超过了YEAR的取值范围。
我们试试向表tmp3中y字段插入2位数字:
INSERTINTO tmp3 VALUES(0),(78),(11);
我们查看一下表tmp3:
SELECT*FROM tmp3;
可以看出0被自动转换成0000,78被转换成1978,11被转换成2011。
2、TIME
其中TIME格式中HH表示小时,MM表示分钟,SS表示秒,在前面的表我们可以发现TIME类型的小时部分取值范围很大,这是因为TIME不仅可以用于表示一天的时间,还可能时某个事件过去的时间或两个事件之间的时间间隔。
这里插入TIME值有两种格式:
- D HH:MM:SS’格式的字符串。可以使用下面任何一种“非严格”的语法:‘HH:MM:SS’、‘HH:MM’、‘D HH:MM’、‘D HH’或‘SS’。这里的D表示日,可以取0~34之间的值。在插入数据库时,D被转换为小时保存,格式为“D*24+HH”。
- ‘HHMMSS’格式的、没有间隔符的字符串或者HHMMSS格式的数值,假定是有意义的时间。例如:‘101112’被理解为‘10:11:12’,但‘109712’是不合法的(它有一个没有意义的分钟部分),存储时将变为00:00:00。
在书写TIME时需要注意的是,如果没有冒号,MySQL会假定最右边的两位表示秒,例如1112,并不是11:12:00,而是00:11:12,相反,TIME中如果使用冒号则肯定被看作当天的时间,也就是11:12就表示11:12:00。
举个例子,创建数据表tmp4,定义字段t的数据类型为TIME,向表中插入值10:05:05、23:23、2 10:10、3 02、10:
CREATETABLE tmp4(t TIME);
向表中插入数据:
INSERTINTO tmp4 VALUES('10:05:05'),('23:23'),('2 10:10'),('3 02'),('10');
查看一下表:
SELECT*FROM tmp4;
我们也可以使用系统日期函数向TIME字段列插入值。
例如,向表tmp4中插入系统当前时间:
INSERTINTO tmp4 VALUES(CURRENT_TIME),(NOW());
查看一下表:
3、DATE
DATE类型用在仅需要日期值时,没有时间部分,格式中的YYYY表示年,MM表示月,DD表示日,在赋值时可以使用字符串类型或者数字类型的数据插入。
举个例子,创建数据表tmp5,字段d的数据类型为DATE:
CREATETABLE tmp5(d DATE);
插入“YYYY-MM-DD”和“YYYYMMDD”格式的数据:
INSERTINTO tmp5 VALUES('1998-08-08'),('19980808'),('20101010');
查看插入结果:
插入“YY-MM-DD”和“YYMMDD”格式的数据:
INSERTINTO tmp5 VALUES('99-09-09'),('990909'),('000101'),('111111');
查看插入结果:
DATE类型也可以插入系统当前日期:
INSERTINTO tmp5 VALUES(CURRENT_DATE()),(NOW());
查看插入结果:
4、DATETIME
DATETIME类型用于需要同时包含日期和时间信息的值,格式中YYYY表示年,MM表示月,DD表示日,HH表示小时,MM表示分钟,SS表示秒。
举个例子,创建数据表tmp6,字段dt的数据类型时DATETIME,向表中插入字符串格式日期和时间值:
CREATETABLE tmp6(dt DATETIME);
插入“YYYY-MM-DD HH:MM:SS”和“YYYYMMDDHHMMSS”格式日期:
INSERTINTO tmp6 VALUES('1998-08-08 08:08:08'),('19980808080808'),('20101010101010');
查看插入结果:
插入“YY-MM-DD HH:MM:SS”和“YYMMDDHHMMSS”格式日期:
INSERTINTO tmp6 VALUES('99-09-09 09:09:09'),('990909090909'),('101010101010');
查看插入结果:
插入系统当前日期和时间:
INSERTINTO tmp6 VALUES(NOW());
查看插入结果:
5、TIMESTAMP
TIMESTAMP的显示格式与DATETIME相同,但TIMESTAMP列的取值范围小于DATETIME的取值范围,其中,UTC(Coordinated Universal Time)为世界标准时间,因此在插入数据时,要保证在合法的取值范围内。
举个例子,创建数据表tmp7,字段ts的数据类型为TIMESTAMP,向表中插入日期:
CREATETABLE tmp7(ts TIMESTAMP);
插入数据:
INSERTINTO tmp7 VALUES('19950101010101'),('950505050505'),('1996-02-02 02:02:02'),('97@03@03 03@03@03'),(121212121212),(NOW());
查看插入结果:
需要注意的是TIMESTAMP与DATETIME除了存储字节和支持的范围不同外,还有一个最大的区别就是:DATETIME在存储日期数据时,按实际输入的格式存储,即输入什么就存储什么,与时区无关;而TIMESTAMP值的存储是以UTC(世界标准时间)格式保存的,存储时对当前时区进行转换,检索时再转换回当前时区。查询时,不同时区显示的时间值是不同的。
我们举个例子说明一下这个:
INSERTINTO tmp7 VALUES(NOW());
这是东8区的时间,我们将时区改成东10区看看:
set time_zone='+10:00';
再次查看一下插入的日期:
可以发现跟之前的时间不同了。
六、最后我想说
数据类型的内容比较多,所以我就分成两篇博客进行总结避免博客篇幅过长影响阅读,接下来还剩下几个数据类型未介绍,后面几天我会尽快更新的。
本期博客介绍的几种数据类型大家可以自行去多练习一下很快就能理解掌握的。
最后谢谢大家能阅读完,我也会继续加油的。