文章目录
整数类型
类型介绍
整数类型一共有五种:
- TINYINT,占1个字节
- SMALLINT,占2个字节
- MEDIUMINT,占3个字节
- INT(INTEGER),占4个字节
- BIGINT,占8个字节
可选属性
- M
- 显示宽度,M的取值范围是 (0,255),需要配合ZEROFILL使用,表示用0填满宽度
- 设置了ZEROFILL,就默认只能是正数,会自动添加UNSIGNED
- 设置了显示宽度,那么,如果插入的数据的宽度超过了显示宽度限制,不会对插入的数据有任何的影响,还是按照类型的实际宽度进行保存。从MySQL 8.0.17开始,整数数据类型不推荐使用显示宽度属性
- 显示宽度,M的取值范围是 (0,255),需要配合ZEROFILL使用,表示用0填满宽度
- UNSIGNED
- 无符号类型(非负),如果在MySQL数据库中保存飞赴整数值时,可以将整数类型设置为无符号类型
- 所有的整数类型都有一个可选的属性UNSIGNED
- ZEROFILL
- 0填充,如果某一列是ZEROFILL,那么MySQL会自动为当前列添加UNSIGNED属性
适用场景
- TINTINT:一般用于枚举数据,比如系统设定取值范围很小且固定的场景
- SMALLINT:可以用于较小的统计数据,比如统计工厂的固定资产库存数量等
- MEDIUMINT:用于较大整数的计算,比如车站每日的客流量等
- INT / INTEGER:取值范围足够大,一般情况下不用考虑超限问题,用得最多,比如商品编号
- BIGINT:只有当处理特别巨大的整数时才会用到。比如双十一的交易量、大型门户网站点击量等
如何选择
在数据不会超过取值范围的情况下,再去考虑节省存储空间。
浮点类型
类型介绍
浮点数和定点数类型的特点是可以处理小数。
MySQL支持的浮点数类型有:FLOAT、DOUBLE、REAL(默认是DOUBLE,和SQL模式有关)。
注意:浮点数类型的无符号取值范围,只相当于有符号取值范围的一半,而整数的话,无符号类型的取值范围是有符号类型正整数部分的两倍
Q:FLOAT 和 DOUBLE 这两种数据类型的区别是什么?
FLOAT占用4个字节,取值范围小;DOUBLE占用8个字节,取值范围大,精度也较高
Q:为什么浮点数类型的无符号数取值范围,只相当于有符号数取值范围的一般,也就是相当于有符号数取值范围中大于等于零的部分?
MySQL存储浮点数的格式为:符号、尾数、阶码,无论有没有符号,MySQL的浮点数都会存储表示符号的部分。因此,所谓的无符号的取值范围,其实就是有符号取值范围中大于等于零的部分。所以,在声明FLOAT、DOUBLE时不用刻意加上UNSIGNED,即使声明了,也不会改变数据范围
数据精度说明
非标准语法:FLOAT(M,D)、DOUBLE(M,D)
- M:精度,D:标度
- M = 整数位 + 小数位,D:小数位
- FLOAT和DOUBLE类型在不指定M和D时,默认会按照实际的精度(由实际的硬件和操作系统决定)
- FLOAT(5,2) 可以表示-999.99 ~ 999.99,如果超出这个范围,会报错
Out of range value for column 'f2' at row 1
不管是否显示地设置了精度(M,D) - 如果存储时,整数部分超出了范围,MySQL就会报错
- 如果存储时,小数部分超出了范围
- 若四舍五入后,整数部分没有超出范围,则只是警告,但能成功操纵并四舍五入删除多余的小数位后保存
- 若四舍五入后 ,整数部分超出范围,则MySQL报错,并拒绝处理
从MySQL8.0.17开始,FLOAT(M,D)和DOUBLE(M,D)用法在官方文档中已经明确不推荐使用
精度误差说明
浮点数类型有个缺陷,就是不精准。问题出于MySQL对浮点类型数据地存储方式上,是采用二进制的方式进行存储,对于尾数不是0或5的小数,就无法用二进制精确表达,只好在取值允许的范围内四舍五入
定点数类型
类型介绍
MySQL中的定点数类型只有DECIMAL。
DECIMAL(M,D),其中M和D一定要指定
DECIMAL(M,D)的最大取值范围和DOUBLE一样,但有效的数据范围由M和D决定,总共占用存储空间为(M+2)字节。
对于一些精度要求不高的场景下,比起占用同样字节长度的定点数,浮点数表达的数值范围可以更大一些
定点数在MySQL内部是以字符串的形式进行存储,这就决定了它一定是精准的
当DECIMAL不指定精度和标度时,默认为DECIAML(10,0)。
浮点数 和 定点数
-
浮点数相对于定点数的优点是:在长度一定的情况下,浮点类型的取值范围大,但是不精准,适用于取值范围大,又可以容忍微小误差的科学计算场景
-
定点数类型取值范围相对较小,但是精准,没有误差,适合于对精度要求极高的场景
日期与时间类型
MySQL8.0中,支持的日期和时间类型有:
- YEAR
- TIME
- DATE
- DATETIME
- TIMESTAMP
YEAR类型
YEAR类型表示年份,占1个字节的存储空间
在MySQL中,YEAR有以下几种存储格式:
- 以4位字符串或数字格式表示YEAR类型,YYYY,范围是1901 ~ 2155
- 以2位字符串格式表示YEAR类型,最小值为00,最大值为99
- 当取值为01到69,表示2001到2069
- 当取值为70到99,表示为190到1999
- 当取整数0或00,表示0000
- 当取字符串’0’,表示2000
从MySQL5.5.27开始,2位格式的YEAR已经不推荐使用
DATE类型
DATE类型表示日期,YYYY-MM-DD,占3个字节
使用CURRENT_DATE()
或NOW()
函数,获取当前系统日期
TIME类型
TIME类型表示时间,HH:MM:SS,占3个字节
使用CURRENT_TIME()
或NOW()
函数,获取当前系统时间
DATETIME类型
在格式上是DATE类型和TIME类型的组合,YYYY-MM-DD HH:MM:SS,占8个字节
最小值是1000-01-01 00:00:00,最大值是9999-12-03 23:59:59
使用CURRENT_TIMESTAMP()
或NOW()
函数,获取当前系统日期和时间
TIMESTAMP类型
TIMESTAMP也表示日期和时间,在格式上与DATETIME一样,YYYY-MM-DD HH:MM:SS,占4个字节
但TIMESTAMP存储的时间范围比DATETIME小,1970-01-01 00:00:01 UTC ~ 2038-01-19 03:14:07 UTC
存储数据的时候需要对当前时间所在的时区进行转换,查询数据的时候再将时间转换回当前的时区。因此,使用TIMESTAMP存储的是同一个时间值,在不同的时区查询,会显示不同的时间
DATETIME 和 TIMESTAMP
- TIMESTAMP存储空间较小,表示的日期和时间范围也较小
- 底层存储方式不同,TIMETAMP底层存储的是毫秒值,距离190-01-01 00:00:00的毫秒数
- 两个日期比较大小或日期计算时,TIMESTAMP更方便、更快
- TIMESTAMP和时区有关。TIMESTAMP跟根据用户的时区不同,显示不同的结果;DATETIME则只能反映出插入时当地的时区,其他时区的人查看数据必然是有误差的