【⑬MySQL | 数据类型(一)】简介 | 整数 | 浮点 | 定点类型
前言
0.数据类型简介
数据类型(data_type)是指系统中所允许的数据的类型。MySQL 数据类型定义了列中可以存储什么数据以及该数据怎样存储的规则。
数据库中的每个列都应该有适当的数据类型,用于限制或允许该列中存储的数据。例如,列中存储的为数字,则相应的数据类型应该为数值类型。
如果使用错误的数据类型可能会严重影响应用程序的功能和性能,所以在设计表时,应该特别重视数据列所用的数据类型。更改包含数据的列不是一件小事,这样做可能会导致数据丢失。因此,在创建表时必须为每个列设置正确的数据类型和长度。
MySQL 的数据类型有大概可以分为 5 种,分别是整数类型、浮点数类型和定点数类型、日期和时间类型、字符串类型、二进制类型等。
注意:整数类型和浮点数类型可以统称为数值数据类型。
1 整数类型
1.1 类型介绍
整数类型包括 TINYINT、SMALLINT、MEDIUMINT、INT、BIGINT
类型 | 说明 | 大小(字节) |
---|---|---|
TINYINT | 很小的整数 | 1 |
SMALLINT | 小的整数 | 2 |
MEDIUMINT | 中等大小的整数 | 3 |
INT/INTEGER | 普通大小的整数 | 4 |
BIGINT | 大整数 | 8 |
1.2 可选属性
1.2.1 M
M:表示显示宽度,M的取值范围是(0,255)。例如,INT(5):当数据小于5位时,可以用字符填充 补满所需宽度。该功能需要配置ZEROFILL
使用,表示用 0 填满宽度,否则指定显示宽度无效。
注意:设置宽度不会对原来的数据或者插入数据产生任何影响,仅仅是显示效果不同。从MySQL 8.0.17开始,整数类型不推荐使用显示宽度属性。
1.2.2 UNSIGNED
所有整数类型都有一个可选的属性UNSIGNED,无符号整数类型的最小取值为0。所以,如果需要在MySQL中保存非负整数是,可以将整数类型设置为无符号类型。
1.3 使用场景
TINYINT:一般用于枚举类型,比如系统设定取值范围很小且固定的场景。
SMALLINT:可以用于较小范围的统计数据,比如统计工厂的固定资产库存数量等。
MEDIUMINT:用于较大整数的计算,比如车站每日的客流量等。
INT、INTEGER:取值范围足够大,一般情况下不用考虑超限问题,用的最多,比如商品编号。
BIGINT:只有当你处理特别巨大的整数时才会用到,比如双十一的交易量、大型门户网站点击量、证券公司衍生产品持仓等。
1.4 如何选择
在评估用哪种整数类型的时候,你需要考虑存储空间
和可靠性
的平衡问题:一方面,用占用字节数少的整数类型可以节省存储空间;另一方面,要是为了节省存储空间,使用的整数类型取值范围太小,一旦遇到超出取值范围的情况,就可能引起系统错误
,影响可靠性。
举个栗子,商品编号采用的数据类型是INT。原因就在于,客户门店中流通的商品种类较多,而且,每天都有旧的商品下架,新的商品上架,这样不断迭代,日积月累。
如果使用 SMALLINT 类型,虽然占用字节数比 INT 类型的证书少,但是却不能保证数据不会超出 655345。相反,使用INT 就能确保有足够大的取值范围,不用担心数据超出范围影响可靠性。
你要注意的是,在实际工作中,系统故障产生的成本远远超过增加几个字段存储空间所产生的成本
。因此,我建议你首先确保数据不会超过取值范围,在这个前提下,再去考虑如何节省存储空间。
2 浮点类型
2.1 类型介绍
浮点数类型包括 FLOAT、DOUBLE和REAL。
类型 | 说明 | 大小(字节) |
---|---|---|
FLOAT | 单精度浮点数 | 4 |
DOUBLE | 双精度浮点数 | 8 |
REAL | 默认为DOUBLE | 把SQL模式设定为“REAL_AS_FLOAT ”,REAL就是FLOATSET sql_mode = "REAL_AS_FLOAT" |
2.2 精度说明
-
MySQL允许使用
非标准语法
(其他数据库未必支持,因此如果涉及到数据前移,则最好不要这么用):FLOAT(M,D)或DOUBLE(M,D)。其中M
称为精度,表示总共的位数;D
称为标度,表示小数的位数。D<=M<=255,0<=D<=30。例如:定义为FLOAT(5,2)的一个列可以显示为[-999.99,999.99],超出这个范围会报错
-
FLOAT 和 DOUBLE 在不指定精度时,默认会按照实际的精度(由计算机硬件和操作系统决定)。
-
注意:浮点类型也可以加
UNSIGNED
,但是不会改变数据范围,例如:FLOAT(3,2) UNSIGNED任然只能表示0-9.99的范围。 -
不管是否显示设置了精度(M,D),MySQL有自己的处理方案:
- 如果存储时,整数部分超出了范围,则直接报错。
- 如果存储时,小数点部分超出范围,就分一下情况:
- 若四舍五入后,整数部分没有超出范围,就可以存储。如在FLOAT(5,2)列插入999.009,近似结果是999.01。
- 若四舍五入后,整数部分超出范围,则直接报错。如在FLOAT(5,2)列插入999.995和-999.995都会报错。
-
从MySQL8.0.17开始,FLOAT(M,D)和DOUBLE(M,D)用法在官方文档中已经明确不推荐使用了,将来可能会被移除;另外关于浮点类型FLOAT和DOUBLE的UNSIGNED也不推荐使用了,将来也可能被移除。
浮点数相对于定点数的优点是在长度一定的情况下,浮点数能够表示更大的范围;缺点是会引起精度问题。
最后再强调一下:在 MySQL 中,定点数以字符串形式存储,在对精度要求比较高的时候(如货币、科学数据),使用 DECIMAL 的类型比较好,另外两个浮点数进行减法和比较运算时也容易出问题,所以在使用浮点数时需要注意,并尽量避免做浮点数比较
3 定点类型
定点数类型为 DECIMAL。
类型 | 说明 | 大小(字节) |
---|---|---|
DECIMAL/DEC | 压缩的“严格”定点数 | M+2 |
DECIMAL(M,D)。其中 包括 YEAR、TIME、DATE、DATETIME 和 TIMESTAMP。 YEAR类型 YEAR 类型是一个单字节类型,用于表示年,在存储时只需要 1 个字节。可以使用各种格式指定 YEAR,如下所示: 从MySQL5.5.27开始,2位格式的YEAR已经不推荐使用。YEAR默认格式就是“YYYY”,没必要写成YEAR(4)。 DATE 类型 DATE 类型用于仅需要日期值时,没有时间部分,在存储时需要 3 个字节。日期格式为 ‘YYYY-MM-DD’,其中 YYYY 表示年,MM 表示月,DD 表示日。 在给 DATE 类型的字段赋值时,可以使用字符串类型或者数字类型的数据插入,只要符合 DATE 的日期格式即可。如下所示: 提示:MySQL 允许“不严格”语法:任何标点符号都可以用作日期部分之间的间隔符。例如,‘98-11-31’、‘98.11.31’、‘98/11/31’和’98@11@31’ 是等价的,这些值也可以正确地插入数据库。 TIME 类型 TIME 类型用于只需要时间信息的值,在存储时需要 3 个字节。格式为 HH:MM:SS。HH 表示小时,MM 表示分钟,SS 表示秒。 TIME 类型的取值范围为 -838:59:59~838:59:59,小时部分如此大的原因是 TIME 类型不仅可以用于表示一天的时间(必须小于 24 小时),还可能是某个事件过去的时间或两个事件之间的时间间隔(可大于 24 小时,或者甚至为负)。 可以使用各种格式指定 TIME 值,如下所示。 提示:为 TIME 列分配简写值时应注意:如果没有冒号,MySQL 解释值时,假定最右边的两位表示秒。(MySQL 解释 TIME 值为过去的时间而不是当前的时间)。例如,读者可能认为 ‘1112’ 和 1112 表示 11:12:00(即 11 点过 12 分钟),但MySQL 将它们解释为 00:11:12(即 11 分 12 秒)。同样 ‘12’ 和 12 被解释为00:00:12。相反,TIME 值中如果使用冒号则肯定被看作当天的时间,也就是说,‘11:12’ 表示 11:12:00,而不是 00:11:12。 DATETIME 类型 DATETIME 类型用于需要同时包含日期和时间信息的值,在存储时需要 8 个字节。日期格式为 ‘YYYY-MM-DD HH:MM:SS’,其中 YYYY 表示年,MM 表示月,DD 表示日,HH 表示小时,MM 表示分钟,SS 表示秒。 在给 DATETIME 类型的字段赋值时,可以使用字符串类型或者数字类型的数据插入,只要符合 DATETIME 的日期格式即可,如下所示。 提示:**MySQL 允许“不严格”语法:任何标点符号都可用作日期部分或时间部分之间的间隔符。**例如,‘98-12-31 11:30:45’、‘98.12.31 11+30+35’、‘98/12/31 113045’ 和 ‘98@12@31 11 ^ 30 ^ 45’ 是等价的,这些值都可以正确地插入数据库。 TIMESTAMP 类型 TIMESTAMP 的显示格式与 DATETIME 相同,显示宽度固定在 19 个字符,日期格式为 YYYY-MM-DD HH:MM:SS,在存储时需要 4 个字节。但是 TIMESTAMP 列的取值范围小于 DATETIME 的取值范围,为 '1970-01-01 00:00:01’UTC~’2038-01-19 03:14:07’UTC。在插入数据时,要保证在合法的取值范围内。 提示:协调世界时(英:Coordinated Universal Time,法:Temps Universel Coordonné)又称为世界统一时间、世界标准时间、国际协调时间。英文(CUT)和法文(TUC)的缩写不同,作为妥协,简称 UTC。 TIMESTAMP 与 DATETIME 除了存储字节和支持的范围不同外,还有一个最大的区别是: 提示:如果为一个 DATETIME 或 TIMESTAMP 对象分配一个 DATE 值,结果值的时间部分被设置为 ‘00:00:00’,因此 DATE 值未包含时间信息。如果为一个 DATE 对象分配一个 DATETIME 或 TIMESTAMP 值,结果值的时间部分被删除,因此DATE 值未包含时间信息。 TIMESTAMP 和 DATETIME区别 TIMESTAMP妙用 TIMESTAMP时间戳在创建的时候可以有多重不同的特性,如: 在创建新记录和修改现有记录的时候都对这个数据列刷新: 在创建新记录的时候把这个字段设置为当前时间,但以后修改时,不再刷新它: 在创建新记录的时候把这个字段设置为0,以后修改时刷新它: 在创建新记录的时候把这个字段设置为给定值,以后修改时刷新它: 模拟用户登录 本来两个时间是一模一样的,但是当用户下线, 总的来说,选择合适的数据类型可以提高数据库的性能、节省存储空间、确保数据的一致性和有效性,并方便进行数据处理和计算。因此,在设计数据库时,选择合适的数据类型非常重要。~下节带来字符串 | 二进制类型的分享 来源地址:https://blog.csdn.net/qq_72157449/article/details/132395966 M
称为精度,表示总共的位数;D
称为标度,表示小数的位数。0<=M<=65,0<=D<=30,D4 日期/时间类型
类型 说明 日期范围 大小(字节) 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:00 UTC ~ 2038-01-19 03:14:07 UTC 4 CREATE TABLE test_year(f1 YEAR, f2 YEAR(4));INSERT INTO test_year(f1) VALUES('2021'),(2022);INSERT INTO test_year(f1) VALUES('2155');-- out of range value for column 'f1' at row 1INSERT INTO test_year(f1) VALUES('2156');INSERT INTO test_year(f1) VALUES('69'),('70');#2069 1970INSERT INTO test_year(f1) VALUES(0),('0');
CREATE TABLE test_date1(f1 DATE);INSERT INTO test_date1 VALUES('2022-04-16'),('20220416'),(20220416);INSERT INTO test_date1 VALUES('22-04-16'),('220416'), ('69-04-16'),('690416'), ('70-04-16'),('700416'), ('99-04-16'),('990416');INSERT INTO test_date1 VALUES(220416),(690416),(700416),(990416);INSERT INTO test_date1 VALUES(CURRENT_DATE()),(NOW());
CREATE TABLE test_time1(f1 TIME);INSERT INTO test_time1 VALUES('10:35:30'),('2 10:35:30'),('10:35'),('2 10:35'),('1 35'),('30');INSERT INTO test_time1 VALUES('103530'),(103530),(1035);INSERT INTO test_time1 VALUES(NOW()),(CURRENT_TIME());
CREATE TABLE test_datetime1(dt DATETIME);INSERT INTO test_datetime1 VALUES('2022-04-16 18:50:30'),('20220416185030');INSERT INTO test_datetime1 VALUES('99-04-16 18:50:30'),('990416185030'), ('22-04-16 18:50:30'),('220416185030');INSERT INTO test_datetime1 VALUES(20220202000000);INSERT INTO test_datetime1 VALUES(CURRENT_TIMESTAMP()),(NOW());
CREATE TABLE test_timestamp(ts TIMESTAMP);INSERT INTO test_timestamp VALUES('1999-01-01 01:02:03'),('1999-01-01 01:02:03'), ('99-01-01 01:02:03'),('990101010203');INSERT INTO test_timestamp VALUES('2022@01@02@11@22@33');INSERT INTO test_timestamp VALUES(CURRENT_TIMESTAMP()),(NOW());
CREATE TABLE temp_time(d1 DATETIME, d2 TIMESTAMP);INSERT INTO temp_time VALUES('2022-04-16 19:09:55','2022-04-16 19:09:55');INSERT INTO temp_time VALUES(NOW(),NOW());SELECT * FROM temp_time;SET time_zone = '+9:00'SELECT * FROM temp_time;#设置之后再查询一次
SET time_zone = '+9:00'
TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
TIMESTAMP DEFAULT CURRENT_TIMESTAMP
TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
TIMESTAMP DEFAULT ‘yyyy-mm-dd hh:mm:ss' ON UPDATE CURRENT_TIMESTAMP
CREATE TABLE t_user(id INT PRIMARY KEY AUTO_INCREMENT,createtime TIMESTAMP DEFAULT CURRENT_TIMESTAMP,lastlogintime TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,is_online TINYINT DEFAULT 0);INSERT INTO t_user(is_online) VALUES(1);SELECT * FROM t_user;# 数据更新UPDATE t_user SET is_online=0 WHERE id=1;
lastlohintime
发生自动更新总结
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341