MySQL【数据类型】
一、数据类型分类

合适的数据类型不仅能节省磁盘空间,还能提升数据查询和操作的效率,甚至避免因数据越界、精度丢失带来的业务问题。
二、 数值类型
数值类型是 MySQL 中最常用的类型之一,用于存储整数、小数等数字数据,又可细分为整型、位类型、浮点型和定点型。整型支持有符号(SIGNED)和无符号(UNSIGNED)两种模式,默认是有符号,无符号类型仅能存储非负数。
整型的核心特点是占用字节固定,取值范围明确,越界插入会直接报错。MySQL 提供了 5 种整型,从 1 字节的 TINYINT 到 8 字节的 BIGINT,满足不同的数值存储需求,其详细参数如下表:
| 类型 | 占用字节 | 有符号范围 | 无符号范围 |
|---|---|---|---|
| TINYINT | 1 | -128 ~ 127 | 0 ~ 255 |
| SMALLINT | 2 | -32768 ~ 32767 | 0 ~ 65535 |
| MEDIUMINT | 3 | -8388608 ~ 8388607 | 0 ~ 16777215 |
| INT | 4 | -2147483648 ~ 2147483647 | 0 ~ 4294967295 |
| BIGINT | 8 | -9223372036854775808 ~ 9223372036854775807 | 0 ~ 18446744073709551615 |
- 越界会直接报错:有符号 TINYINT 插入 128、无符号 TINYINT 插入 - 1,都会触发
Out of range错误,MySQL 不会自动转换值; - 慎用 UNSIGNED:官方建议尽量不使用无符号类型,若 INT 存储不下数据,INT UNSIGNED 也大概率存不下,直接将类型提升为 BIGINT 更稳妥;
- BOOL 本质是 TINYINT (1):MySQL 中没有真正的布尔类型,BOOL/BOOLEAN 是 TINYINT (1) 的别名,用 0 表示假,1 表示真。
2.1 tinyint类型
越界测试



在MySQL中 , 整型可以指定是有符号和无符号的 , 默认是有符号的可以通过UNSIGNED来说明某个字段是无符号的以上的案例我们可以知道 , 如果不在合法的数据范围 , 会发生直接拦截 , 不允许进行数据的插入 , 一定程度上约束了用户对数据的插入。

从另外一个方面来看 , 如果数据成功的插入的表格中 , 这个数据一定是合法的(或者做过一些符合规范的数据处理,比方说后面所说的浮点数)。Mysql 能保证数据插入的合法性 , 就能数据库中的数据是可预期性的 【数据访问已知】、完整的【没有发生半阶段和类型转化】对于类型的选择,一般视情况而论,比方说 , 年龄不会出现负数,我们就可以使用unsigned类型 ~
2.2 bit 类型
基本语法:

显示规则特殊:BIT 字段查询时,会按照ASCII 码对应的值显示,而非直接显示数字。例如插入 65,会显示字符 'A';精准控制存储位数:适合存储仅 0/1 的状态值(如性别:0 - 女,1 - 男),定义为BIT(1)可最大限度节省空间;越界会报错:插入的值超过 M 位表示的范围,会触发Data too long错误。


bit 字段在显示的时候 , 是按照ASCII码对应的值显示 。上面的2插入失败的原因是 , 越界了 , 定义online的类型是 bit(1) ;如果想要显示出 0/1可以使用查询的方式打开 , 以16进制的方式显示出来~



使用合适的数据类型,不但可以满足应用场景 , 还可以节省资源【空间】;
三、小数类型
当需要存储带小数的数值(如金额、薪资、身高)时,需使用浮点型(FLOAT/DOUBLE)或定点型(DECIMAL),二者的核心区别是精度不同,浮点型存在精度丢失,定点型则精准存储。
3.1 float
语法:

FLOAT:占用 4 字节,精度约 7 位,语法FLOAT[(M,D)] [UNSIGNED];DOUBLE:占用 8 字节,精度比 FLOAT 更高,语法DOUBLE[(M,D)] [UNSIGNED];其中M表示显示长度(整数 + 小数的总位数),D表示小数位数,MySQL 会对插入的值进行四舍五入处理。【前提是要在合法的大小内】核心特性:FLOAT(4,2)表示总长度 4 位、小数 2 位,有符号范围为-99.99 ~ 99.99,无符号范围为0 ~ 99.99;若插入值的小数位超过 D,会自动四舍五入,若整体超过 M 则越界报错。


用浮点数来表示数据,由于浮点数的特殊性 , 可能有一些数据会存在精度丢失。
3.2 decimal
语法:

DECIMAL 是定点数,语法DECIMAL(M,D) [UNSIGNED],与浮点型参数含义一致,但不会丢失精度,是存储金额、汇率等财务数据的首选。



- 发现decimal的精度更加准确 , 因此如果我们希望某个数据表示高精度 , 选择decimal
- 浮点型 vs 定点型核心区别
| 特性 | FLOAT/DOUBLE | DECIMAL |
|---|---|---|
| 精度 | 约 7 位(FLOAT),更高(DOUBLE) | 精准,无丢失 |
| 占用空间 | 固定(4/8 字节) | 随 M/D 变化 |
| M/D 范围 | 无严格大限制 | M 最大 65,D 最大 30,默认 D=0、M=10 |
| 适用场景 | 普通小数(如身高、体重) | 高精度小数(如金额、薪资) |
四、字符串类型
MySQL 的字符串类型主要包括定长 CHAR、变长 VARCHAR,以及存储大文本 / 二进制的TEXT/BLOB,其中 CHAR 和 VARCHAR 是日常使用最频繁的类型,核心区别在于存储方式和空间占用。
4.1 char
语法:

固定空间:无论实际存储的字符数多少,都会开辟 L 个字符对应的字节空间,例如CHAR(2)存储ab和中国,都占用 2 个字符的空间;效率更高:因为空间固定,MySQL 无需计算实际存储长度,查询和写入速度更快;字符兼容:支持字母、数字、汉字等所有字符,L 表示字符数,而非字节数(如 utf8 编码下,1 个汉字占 3 字节,CHAR(2)可存 2 个汉字)。


char(2) 可以存放两个字符 , 可以是字母或者汉字 , 但是不可以超过2个,最多只能是255
4.2 varchar
语法:

语法VARCHAR(L),其中L 表示最大字符数,单位是字符,其最大存储能力与表的编码格式密切相关,核心原因是 MySQL 行最大字节数为 65535,且 VARCHAR 会用 1~3 个字节记录数据的实际长度。
动态空间:实际占用空间 =字符实际字节数 + 1~3 个长度记录字节,例如VARCHAR(4)存储A,仅占用 1 个字符的字节 + 1 个长度字节,节省空间;编码限制 L 的最大值:utf8 编码:1 个字符占 3 字节,L 最大值 = 65532/3=21844;gbk 编码:1 个字符占 2 字节,L 最大值 = 65532/2=32766;字符兼容:与 CHAR 一致,L 表示字符数,支持多类型字符。


4.3 char 和 varchar比较
| 实际存储内容 | CHAR (4) 存储 | VARCHAR (4) 存储 | CHAR 占用字节 | VARCHAR 占用字节 |
|---|---|---|---|---|
| abcd | abcd | abcd | 4*3=12 | 4*3+1=13 |
| A | A(补空格) | A | 4*3=12 | 1*3+1=4 |
| Abcde | 越界报错 | 越界报错 | 数据超长 | 数据超长 |

选 CHAR 的场景:数据长度固定不变,追求操作效率,例如身份证号、手机号、MD5 值、邮编等;选 VARCHAR 的场景:数据长度不固定,需要节省空间,例如姓名、地址、商品名称等,注意保证 L 能容纳最长的内容;选 TEXT/BLOB 的场景:存储超长篇幅的内容,例如文章正文、图片二进制数据、日志内容等(TEXT 不支持全文索引和默认值)。
五、日期和时间类型
MySQL 提供了 DATE、DATETIME、TIMESTAMP 三种常用的日期时间类型,分别适配不同的时间存储需求,核心区别在于存储格式、占用字节和自动更新特性,其中 TIMESTAMP 的自动更新是实战中的常用技巧。
| 类型 | 存储格式 | 占用字节 | 时间范围 | 核心特性 |
|---|---|---|---|---|
| DATE | yyyy-mm-dd | 3 | 1000-01-01 ~ 9999-12-31 | 仅存储日期,无时间 |
| DATETIME | yyyy-mm-dd hh:mm:ss | 8 | 1000-01-01 ~ 9999-12-31 | 存储日期 + 时间,无自动更新 |
| TIMESTAMP | yyyy-mm-dd hh:mm:ss | 4 | 1970-01-01 ~ 2038-01-19 | 存储日期 + 时间,支持自动更新 |
TIMESTAMP 是时间戳类型,基于 1970-01-01 00:00:00(UTC)开始的秒数计算,其最核心的特性是自动补全和自动更新:插入数据时,若未给 TIMESTAMP 字段赋值,会自动填充当前系统时间;更新数据时,若未修改 TIMESTAMP 字段,会自动更新为当前系统时间。
该特性非常适合存储数据创建时间和数据更新时间,无需手动赋值,简化业务代码。



timestamp的作用是什么?
例如:发表评论:


显示评论发布的时间~

更新的时间~
datetime的作用是什么?
让程序员去维护不会随时间变化的时间,存储固定的时间 。场景:入职时间,离职时间。
date的作用是什么?
只记录日期。场景:结婚日期,生日时间。
六、enum 和set
语法:



在业务中,经常会遇到单选(如性别:男 / 女)、多选(如爱好:登山 / 游泳 / 篮球)的场景,若使用 VARCHAR 存储,会导致数据不规范、查询困难,而 MySQL 提供的ENUM和SET类型可完美解决该问题,二者均为字符串对象,底层以数字存储,效率更高。


枚举约束,不允许插入其他数据




是否有招商银行的账号:
1. 有 , 但是没钱,空串
2. 没有 NULL



枚举的时候写数值代表下标set的时候写数值代表位图插入:可以字面值 , 也可以使用数值
如何进行查找?




但是如果我需要的是把爱好有羽毛球的筛选出来,而不是把爱好只要羽毛球的筛选出,该如何解决?
find_in_set函数
学习mysql的一个筛选函数 find_in_set



所以,对于在hobby集合中查找有羽毛球爱好的人,我们可以这么写:


数据类型就是mysql中天然的约束,如果存在 且满足这个约束,mysql允许你插入数据,如果不是很匹配,例如浮点数,mysql会做它的处理 , 其余的不满足约束 , 则拒绝插入 。