MySQL-相关数据类型

MySQL-数据类型

整数类型

整数类型包含以下五种:

整数类型 字节 说明
tinyint 1 一般用于枚举数据,比如系统设定取值范围很小且固定的场景。
smallint 2 可以用于较小范围的统计数据,比如统计工厂的固定资产库存数量等。
mediumint 3 用于较大整数的计算,比如车站每日的客流量等。
int、integer 4 取值范围足够大,一般情况下不用考虑超限问题,用得最多。比如商品编号。
bigint 8 处理特别巨大的整数时才会用到。比如大型门户网站点击量

可选属性

①M:表示显示宽度,M的取值范围是(0, 255)。例如,int(5):当数据宽度小于5位的时候在数字前面需要用 字符填满宽度。该项功能需要配合" ZEROFILL "使用,表示用"0"填满宽度,否则指定显示宽度无效。如
sql 复制代码
alter table rqtanc add number int(10) zerofill
显示宽度与数据类型可以存储的值范围无关,但在 MySQL 8 中不在推荐使用 显示数据宽度属性
②UNSIGNED:无符号类型(非负),int类型默认显示宽度为int(11),无符号int类型默认显示宽度为int(10)。如:
sql 复制代码
alter table rqtanc add number int(10) unsigned zerofill;
③ZEROFILL: 0填充,如果某列是ZEROFILL,MySQL会自动为当前列添加UNSIGNED属性,如果指 定了ZEROFILL只是表示不够M位时,用0在左边填充,如果超过M位,只要不超过数据存储范围即可。int(M),必须和UNSIGNED ZEROFILL一起使用才有意义。如果整 数值超过M位,就按照实际位数存储。只是无须再用字符 0 进行填充。

浮点类型

浮点数类型,分别是 FLOAT、DOUBLE、REAL。REAL默认情况下就是DOUBLE,通过

sql 复制代码
SET sql_mode = 'REAL_AS_FLOAT';

设置为REAL 为FLOAT单精度浮点数

FLOAT:表示单精度浮点数;DOUBLE:表示双精度浮点数

类型 字节
FLOAT 4
DOUBLE 8

存储浮点数的格式为: 符号(S) 、 尾数(M) 和 阶码(E)

相关精度说明

①允许使用 非标准语法, FLOAT(M,D) 或 DOUBLE(M,D),M称为 精度 ,D称为 标度 。(M,D)中 M=整数位+小数 位,D=小数位。 D<=M<=255,0<=D<=30。
②FLOAT和DOUBLE类型在不指定(M,D)时,默认会按照实际的精度(由实际的硬件和操作系统决定) 来显示。
③浮点类型,也可以加 UNSIGNED(表示非负) ,但是不会改变数据范围
④相关处理方案:
Ⅰ如果存储时,整数部分超出了范围就会报错,不允许存这样的值
Ⅱ如果存储时,小数点部分若超出范围,分为以下两种情况:
1.若四舍五入后,整数部分没有超出范围,则只警告,但能成功操作并四舍五入删除多余 的小数位后保存。
2.若四舍五入后,整数部分超出范围,则MySQL报错,并拒绝处理

注意:

①FLOAT(M,D) 和DOUBLE(M,D),浮点型FLOAT和DOUBLE的UNSIGNED 在8.0及以后版本不在推荐使用
②浮点数是不准确的,所以我们要避免使用"="来 判断两个数是否相等

定点数类型

只有 DECIMAL 一种类型。

类型 字节 说明
DECIMAL(M,D),DEC,NUMERIC M+2 有效范围由M和D决定

相关说明:

①使用 DECIMAL(M,D) 的方式表示高精度小数。其中,M被称为精度,D被称为标度。0<=M<=65, 0<=D<=30,D<M。
②DECIMAL(M,D)的最大取值范围与DOUBLE类型一样,但是有效的数据范围是由M和D决定的。
③定点数在MySQL内部是以 字符串 的形式进行存储,这就决定了它一定是精准的。
④当DECIMAL类型不指定精度和标度时,其默认为DECIMAL(10,0)。当数据的精度超出了定点数类型的 精度范围时,则MySQL同样会进行四舍五入处理。
⑤定点数类型取值范围相对小,但是精准,没有误差,适合于对精度要求极高的场景 (比如涉 及金额计算的场景)

位类型:BIT

BIT类型中存储的是二进制值,类似010110。

类型 长度 范围 占用空间
BIT(M) M 1<=M<=64 约(M+7)/8

相关说明

①如果没有指定(M),默认是1位。这个1位,表示只能存1位的二进制值。这里(M)是表示二进制的 位数,位数最小值为1,最大值为64。
②在向BIT类型的字段中插入数据时,一定要确保插入的数据在BIT类型支持的范围内。
③使用b+0查询数据时,可以直接查询出存储的十进制数据的值

日期与时间类型

日期和时间 类型主要有:YEAR类型、TIME类型、DATE类型、DATETIME类型和TIMESTAMP类型。

类型 说明 字节 格式
YEAR 1 YYYY或YY
TIME 时间 3 HH:MM:SS
DATE 日期 3 YYYY-MM-DD
DATETIME 日期 时间 8 YYYY-MM-DD HH:MM:SS
TIMESTAMP 日期 时间 4 YYYY-MM-DD HH:MM:SS

相关说明

YEAR类型
①用来表示年份,在所有的日期时间类型中所占用的存储空间最小,只需要 1个字节 的存储空间。
②存储格式如下:
Ⅰ:以4位字符串或数字格式表示YEAR类型,其格式为YYYY,最小值为1901,最大值为2155。
Ⅱ:以2位字符串格式表示YEAR类型,最小值为00,最大值为99。
Ⅲ:5.5.27版本不在推荐使用YY格式,8.0.19版本不在推荐使用显示宽度格式YEAR(4)

DATE类型
①表示日期,没有时间部分,格式为 YYYY-MM-DD ,其中,YYYY表示年份,MM表示月份,DD表示 日期。需要 3个字节 的存储空间。
②存储格式如下:
Ⅰ:以 YYYY-MM-DD 格式或者 YYYYMMDD 格式表示的字符串日期。YYYYMMDD格式会被转化为YYYY-MM-DD格式。
Ⅱ:以 YY-MM-DD 格式或者 YYMMDD 格式表示的字符串日期,此格式中,年份为两位数值或字符串满足 YEAR类型的格式条件为:当年份取值为00到69时,会被转化为2000到2069;当年份取值为70到99 时,会被转化为1970到1999。
Ⅲ:使用 CURRENT_DATE() 或者 NOW() 函数,会插入当前系统的日期。

TIME类型:
①用来表示时间,不包含日期部分。在MySQL中,需要 3个字节 的存储空间来存储TIME类型的数 据,可以使用"HH:MM:SS"格式来表示TIME类型,其中,HH表示小时,MM表示分钟,SS表示秒。
存储格式说明:
Ⅰ:可以使用带有冒号的 字符串,比如' D HH:MM:SS' 、' HH:MM:SS '、' HH:MM '、' D HH:MM '、' D HH '或' SS '格式,其中D表示天,其最小值为0,最大值为34。如果使用带有D格式的字符串 插入TIME类型的字段时,D会被转化为小时,计算格式为D*24+HH。当使用带有冒号并且不带D的字符串 表示时间时,表示当天的时间,比如12:10表示12:10:00,而不是00:12:10
Ⅱ:使用不带有冒号的 字符串或者数字,格式为' HHMMSS '或者 HHMMSS 。
Ⅲ:使用 CURRENT_TIME() 或者 NOW() ,会插入当前系统的时间

DATETIME类型
①在所有的日期时间类型中占用的存储空间最大,总共需要 8 个字节的存储空间。在格式上 为DATE类型和TIME类型的组合,可以表示为 YYYY-MM-DD HH:MM:SS ,其中YYYY表示年份,MM表示月 份,DD表示日期,HH表示小时,MM表示分钟,SS表示秒。
②存储格式说明:
Ⅰ:以 YYYY-MM-DD HH:MM:SS 格式或者 YYYYMMDDHHMMSS 格式的字符串插入DATETIME类型的字段时, 最小值为1000-01-01 00:00:00,最大值为9999-12-03 23:59:59。
Ⅱ:以YYYYMMDDHHMMSS格式的数字插入DATETIME类型的字段时,会被转化为YYYY-MM-DD HH:MM:SS格式。
Ⅲ:使用函数 CURRENT_TIMESTAMP() 和 NOW() ,可以向DATETIME类型的字段插入系统的当前日期和 时间。

TIMESTAMP类型
①TIMESTAMP类型也可以表示日期时间,其显示格式与DATETIME类型相同,都是 YYYY-MM-DD HH:MM:SS ,需要4个字节的存储空间。但是TIMESTAMP存储的时间范围比DATETIME要小很多
②存储数据的时候需要对当前时间所在的时区进行转换,查询数据的时候再将时间转换回当前的时 区。因此,使用TIMESTAMP存储的同一个时间值,在不同的时区查询时会显示不同的时间。
③修改当前市区:
sql 复制代码
SET time_zone = '+9:00';

CHAR与VARCHAR类型

都可以存储比较短的字符串。

类型 特点 长度 范围 存储空间
CHAR(M) 固定长度 M 0 <= M <= 255 M个字节
VARCHAR(M) 可变长度 M 0 <= M <= 65535 (实际长度 + 1) 个字节

CHAR类型:

①CHAR(M) 类型一般需要预先定义字符串长度。如果不指定(M),则表示长度默认是1个字符。
②保存时,数据的实际长度比CHAR类型声明的长度小,则会在 右侧填充 空格以达到指定的长 度。当MySQL检索CHAR类型的数据时,CHAR类型的字段会去除尾部的空格。
③ 定义CHAR类型字段时,声明的字段长度即为CHAR类型字段所占的存储空间的字节数。

VARCHAR类型:

①VARCHAR(M) 定义时, 必须指定 长度M,否则报错。
②varchar(20):指的是20字符。
③ 检索VARCHAR类型的字段数据时,会保留数据尾部的空格。VARCHAR类型的字段所占用的存储空间 为字符串实际长度加1个字节。

对比:

类型 特点 空间上 时间上 适用场景
CHAR(M) 固定长度 浪费存储空间 效率高 存储不大,速度要求高
VARCHAR(M) 可变长度 节省存储空间 效率低 非CHAR的情况

不同存储引擎相关说明:

①MyISAM 数据存储引擎和数据列:MyISAM数据表,最好使用固定长度(CHAR)的数据列代替可变长 度(VARCHAR)的数据列。这样使得整个表静态化,从而使 数据检索更快 ,用空间换时间。
②MEMORY 存储引擎和数据列:MEMORY数据表目前都使用固定长度的数据行存储,因此无论使用 CHAR或VARCHAR列都没有关系,两者都是作为CHAR类型处理的。
③ InnoDB 存储引擎,建议使用VARCHAR类型。因为对于InnoDB数据表,内部的行存储格式并没有区 分固定长度和可变长度列(所有数据行都使用指向数据列值的头指针),而且主要影响性能的因素 是数据行使用的存储总量,由于char平均占用的空间多于varchar,所以除了简短并且固定长度的, 其他考虑varchar。这样节省空间,对磁盘I/O和数据存储总量比较好。

TEXT类型

TEXT用来保存文本类型的字符串,总共包含4种类型,分别为TINYTEXT、TEXT、 MEDIUMTEXT 和 LONGTEXT 类型。

类型 特点 长度 长度范围 占用的存储空
TINYTEXT 小文本、可变长度 L 0 <= L <= 255 L + 2 个字节
TEXT 文本、可变长度 L 0 <= L <= 65535 L + 2 个字节
MEDIUMTEXT 中等文本、可变长度 L 0 <= L <= 16777215 L + 3 个字节
LONGTEXT 大文本、可变长度 L 0 <= L<= 4294967295(相当于 4GB) L + 4 个字节

相关说明:

①由于实际存储的长度不确定,MySQL 不允许 TEXT 类型的字段做主键。遇到这种情况,你只能采用 CHAR(M),或者 VARCHAR(M)。
②TEXT文本类型,可以存比较大的文本段,搜索速度稍慢,因此如果不是特别大的内容,建议使用CHAR, VARCHAR来代替。
③TEXT类型不用加默认值,添加也无任何意义
④且text和blob类型的数据删除后容易导致 "空洞",使得文件碎片比较多,所以频繁使用的表不建议包含TEXT类型字段,建议单独分出去,单独用 一个表。

ENUM类型

ENUM类型也叫作枚举类型,ENUM类型的取值范围需要在定义字段时进行指定。设置字段值时,ENUM 类型只允许从成员中选取单个值,不能一次选取多个值。

其所需要的存储空间由定义ENUM类型时指定的成员个数决定。

类型 长度 长度范围 占用的存储空间
ENUM L 1 <= L <= 65535 1或2个字节

相关说明:

①当ENUM类型包含1~255个成员时,需要1个字节的存储空间;
②当ENUM类型包含256~65535个成员时,需要2个字节的存储空间。
③ ENUM类型的成员个数的上限为65535个。

示例:

sql 复制代码
CREATE TABLE test_enum(
season ENUM('春','夏','秋','冬','unknow')
);

INSERT INTO test_enum
VALUES('春'),('秋');
# 忽略大小写
INSERT INTO test_enum
VALUES('UNKNOW');
# 允许按照角标的方式获取指定索引位置的枚举值
INSERT INTO test_enum
VALUES('1'),(3);
# Data truncated for column 'season' at row 1
INSERT INTO test_enum
VALUES('ab');
# 当ENUM类型的字段没有声明为NOT NULL时,插入NULL也是有效的
INSERT INTO test_enum
VALUES(NULL);

SET类型

当SET类型包含的成员个数不同时,其所占用的存储空间也是不同的,具体如下:

成员个数范围(L表示实际成员个数) 占用的存储空间
1 <= L <= 8 1个字节
9 <= L <= 16 2个字节
17 <= L <= 24 3个字节
25 <= L <= 32 4个字节
33 <= L <= 64 8个字节

SET类型在存储数据时成员个数越多,其占用的存储空间越大。注意:SET类型在选取成员时,可以一次 选择多个成员,这一点与ENUM类型不同。

示例

sql 复制代码
CREATE TABLE test_set(
s SET ('A', 'B', 'C')
);


INSERT INTO test_set (s) VALUES ('A'), ('A,B');
#插入重复的SET类型成员时,MySQL会自动删除重复的成员
INSERT INTO test_set (s) VALUES ('A,B,C,A');
#向SET类型的字段插入SET成员中不存在的值时,MySQL会抛出错误。
INSERT INTO test_set (s) VALUES ('A,B,C,D');
SELECT *
FROM test_set;

二进制字符串类型

二进制字符串类型主要存储一些二进制数据,比如可以存储图片、音频和视频等二进制数 据。

二进制字符串类型主要包括BINARY、VARBINARY、TINYBLOB、BLOB、MEDIUMBLOB 和 LONGBLOB类型。


BINARY与VARBINARY类型

①BINARY和VARBINARY类似于CHAR和VARCHAR,只是它们存储的是二进制字符串。
②BINARY (M)为固定长度的二进制字符串,M表示最多能存储的字节数,取值范围是0~255个字符。如果未 指定(M),表示只能存储 1个字节 。如果字段值不足(M)个字 节,将在右边填充'\0'以补齐指定长度。
③VARBINARY (M)为可变长度的二进制字符串,M表示最多能存储的字节数,总字节数不能超过行的字节长 度限制65535,另外还要考虑额外字节开销,VARBINARY类型的数据除了存储数据本身外,还需要1或2个 字节来存储数据的字节数。VARBINARY类型 必须指定(M) ,否则报错。
二进制字符串类型 特点 值的长度 占用空间
BINARY(M) 固定长度 M (0 <= M <= 255) M个字节
VARBINARY(M) 可变长度 M(0 <= M <= 65535) M+1个字节
示例:
sql 复制代码
CREATE TABLE test_binary1(
f1 BINARY,
f2 BINARY(3),
# f3 VARBINARY,
f4 VARBINARY(10)
);

INSERT INTO test_binary1(f2,f4)
VALUES('ab','ab');
mysql> SELECT LENGTH(f2),LENGTH(f4)
-> FROM test_binary1;
+------------+------------+
| LENGTH(f2) | LENGTH(f4) |
+------------+------------+
| 3 | NULL |
| 3 | 2 |
+------------+------------+
INSERT INTO test_binary1(f1,f2)
VALUES('a','a');
INSERT INTO test_binary1(f1,f2)
VALUES('尚','尚');#失败

BLOB类型

①的BLOB类型包括TINYBLOB、BLOB、MEDIUMBLOB和LONGBLOB 4种类型,它们可容纳值的最大 长度不同。可以存储一个二进制的大对象,比如 图片 、 音频 和 视频 等。
②在实际工作中,往往不会在MySQL数据库中使用BLOB类型存储大对象数据,通常会将图 片、音频和视频文件存储到 服务器的磁盘上 ,并将图片、音频和视频的访问路径存储到MySQL中。
二进制字符串类型 值的长度 长度范围 占用空间
TINYBLOB L 0 <= L <= 255 L + 1 个字节
BLOB L 0 <= L <= 65535(相当于64KB) L + 2 个字节
MEDIUMBLOB L 0 <= L <= 16777215 (相当于16MB) L + 3 个字节
LONGBLOB L 0 <= L <= 4294967295(相当于4GB) L + 4 个字节
TEXT和BLOB的使用注意事项:
① BLOB和TEXT值也会引起自己的一些问题,特别是执行了大量的删除或更新操作的时候。删除这种值 会在数据表中留下很大的" 空洞 ",以后填入这些"空洞"的记录可能长度不同。为了提高性能,建议定期 使用 OPTIMIZE TABLE 功能对这类表进行 碎片整理 。
② 如果需要对大文本字段进行模糊查询,MySQL 提供了 前缀索引 。但是仍然要在不必要的时候避免检 索大型的BLOB或TEXT值。例如,SELECT * 查询就不是很好的想法,除非你能够确定作为约束条件的 WHERE子句只会找到所需要的数据行。否则,你可能毫无目的地在网络上传输大量的值。
③ 把BLOB或TEXT列 分离到单独的表 中。在某些环境中,如果把这些数据列移动到第二张数据表中,可 以让你把原数据表中的数据列转换为固定长度的数据行格式,那么它就是有意义的。这会 减少主表中的 碎片 ,使你得到固定长度数据行的性能优势。它还使你在主数据表上运行 SELECT * 查询的时候不会通过 网络传输大量的BLOB或TEXT值。

JSON 类型

①JSON(JavaScript Object Notation)是一种轻量级的 数据交换格式 。简洁和清晰的层次结构使得 JSON 成 为理想的数据交换语言。它易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效 率。JSON 可以将 JavaScript 对象中表示的一组数据转换为字符串,然后就可以在网络或者程序之间轻 松地传递这个字符串,并在需要的时候将它还原为各编程语言所支持的数据格式。

②在MySQL 5.7中,就已经支持JSON数据类型

③在MySQL 8.x版本中,JSON类型提供了可以进行自动验证的 JSON文档和优化的存储结构,使得在MySQL中存储和读取JSON类型的数据更加方便和高效。 创建数据 表,表中包含一个JSON类型的字段 js 。

示例:

sql 复制代码
create table test_json(
js json
);

INSERT INTO test_json (js)
VALUES ('{"name":"songhk", "age":18, "address":{"province":"beijing",
"city":"beijing"}}');

当需要检索JSON类型的字段中数据的某个具体值时,可以使用"->"和"->>"符号。

sql 复制代码
mysql> SELECT js -> '$.name' AS NAME,js -> '$.age' AS age ,js -> '$.address.province'
AS province, js -> '$.address.city' AS city
-> FROM test_json;
+----------+------+-----------+-----------+
| NAME | age | province | city |
+----------+------+-----------+-----------+
| "songhk" | 18 | "beijing" | "beijing" |
+----------+------+-----------+-----------+
1 row in set (0.00 sec)

相关建议:

①任何字段如果为非负数,必须是 UNSIGNED

②小数类型为 DECIMAL,禁止使用 FLOAT 和 DOUBLE。

③如果存储的字符串长度几乎相等,使用 CHAR 定长字符串类型。

④VARCHAR 是可变长字符串,不预先分配存储空间,长度不要超过 5000。如果存储长度大 于此值,定义字段类型为 TEXT,独立出来一张表,用主键来对应,避免影响其它字段索引效率。

相关推荐
难以触及的高度33 分钟前
mysql中between and怎么用
数据库·mysql
Jacky(易小天)1 小时前
MongoDB比较查询操作符中英对照表及实例详解
数据库·mongodb·typescript·比较操作符
Karoku0661 小时前
【企业级分布式系统】ELK优化
运维·服务器·数据库·elk·elasticsearch
小技与小术3 小时前
数据库表设计范式
数据库·mysql
安迁岚3 小时前
【SQL Server】华中农业大学空间数据库实验报告 实验三 数据操作
运维·服务器·数据库·sql·mysql
安迁岚3 小时前
【SQL Server】华中农业大学空间数据库实验报告 实验九 触发器
数据库·sql·mysql·oracle·实验报告
Loganer3 小时前
MongoDB分片集群搭建
数据库·mongodb
LKID体3 小时前
Python操作neo4j库py2neo使用之创建和查询(二)
数据库·python·neo4j
刘大浪3 小时前
后端数据增删改查基于Springboot+mybatis mysql 时间根据当时时间自动填充,数据库连接查询不一致,mysql数据库连接不好用
数据库·spring boot·mybatis
一只爱撸猫的程序猿3 小时前
简单实现一个系统升级过程中的数据平滑迁移的场景实例
数据库·spring boot·程序员