4. 数据类型
4.1 数据类型分类

4.2 数值类型

4.2.1 tinyint 类型
-
说明 :占 1 字节的整数类型,默认是有符号 (范围:-128 ~ 127),可通过
UNSIGNED指定为无符号(范围:0 ~ 255)。 -
数值越界测试 :
sql-- 创建表,字段num为tinyint(默认有符号) create table tt1(num tinyint); insert into tt1 values(1); -- 正常插入(1在-128~127范围内) insert into tt1 values(128); -- 越界,报错:Out of range value -
无符号案例 :
sqlcreate table tt2(num tinyint unsigned); -- 无符号tinyint insert into tt2 values(-1); -- 越界(无符号范围0~255),报错 insert into tt2 values(255); -- 正常插入(255在0~255范围内) -
注意事项 :
- 尽量不使用
unsigned(无符号),若 int 类型存不下数据,int unsigned也可能存不下,建议直接使用更大类型(如 bigint)。 - 如果我们向mysql特定的类型中插入不合法的数据,MySQL一般都是直接拦截的,不让我们做对应的操作!
反过来,如果我们已经有数据被成功插入到mysql中了,那么该数据插入的时候一定是合法的!
所以mysql数据类型本身也是一种"约束"。
- 尽量不使用
4.2.2 bit 类型
-
语法 :
bit[(M)],M 表示位数(1~64,默认 1),用于存储位数据。 -
案例 :
sqlcreate table tt4(id int, a bit(8)); -- a为8位bit类型 insert into tt4 values(10, 10); -- 插入数值10(二进制1010) insert into tt4 values(65, 65); -- 插入数值65(对应ASCII码'A') -
显示特性 :bit 字段按ASCII 码对应的值显示(如 65 显示为 'A',10 无对应可打印 ASCII 码,显示为空)。
-
使用场景 :仅需存储 0 或 1 时,用
bit(1)可节省空间(如性别:0 代表女,1 代表男)。 -
越界测试 :
sqlcreate table tt5(gender bit(1)); -- 1位bit,仅能存0或1 insert into tt5 values(2); -- 越界(2的二进制为10,超过1位),报错:Data too long
4.2.3 小数类型
用于存储带小数点的数值,分为float(单精度)和decimal(定点数,高精度)。
4.2.3.1 float 类型
-
语法 :
float[(m, d)] [unsigned],m 为总长度(整数 + 小数位数),d 为小数位数,占 4 字节。 -
范围 :
- 有符号:
float(m,d)范围为-10^(m-d) + 0.10^-d~10^(m-d) - 0.10^-d(如float(4,2)范围:-99.99 ~ 99.99); - 无符号:范围为
0 ~ 10^(m-d) - 0.10^-d(如float(4,2) unsigned范围:0 ~ 99.99)。
- 有符号:
-
特性 :插入时会自动四舍五入保留 d 位小数。
-
案例 :
sqlcreate table tt6(id int, salary float(4,2)); -- 总长度4,小数2位 insert into tt6 values(101, -99.991); -- 四舍五入为-99.99

- 当字段值超出定义范围就会报错

4.2.3.2 decimal 类型
-
语法 :
decimal(m, d) [unsigned],m 为总长度(最大 65),d 为小数位数(最大 30,默认 0),精度高于 float。 -
范围 :
- 有符号:
decimal(5,2)范围:-999.99 ~ 999.99; - 无符号:
decimal(5,2) unsigned范围:0 ~ 999.99。
- 有符号:
-
与 float 的区别 :
- float 精度约 7 位(可能有精度损失);
- decimal 为定点数,精度更高(无损失),适合存储高精度数据(如货币、金额)。
-
案例 :
sqlcreate table tt8(id int, salary float(10,8), salary2 decimal(10,8)); insert into tt8 values(100, 23.12345612, 23.12345612); select * from tt8; -- 输出:salary显示23.12345695(精度损失),salary2显示23.12345612(精确)
4.3 字符串类型
用于存储文本数据,主要有char(固定长度)和varchar(可变长度)。
4.3.1 char 类型
-
语法 :
char(L),L 为字符长度(1~255,单位为字符,支持字母、汉字等)。 -
特性:长度固定,无论实际存储内容长短,均占用 L 个字符的空间(不足则补空格,查询时自动去除尾部空格)。
-
案例 :
sqlcreate table tt9(id int, name char(2)); -- 最多存2个字符 insert into tt9 values(100, 'ab'); -- 正常(2个字母) insert into tt9 values(101, '中国'); -- 正常(2个汉字) create table tt10(id int, name char(256)); -- 报错(超过最大长度255)
4.3.2 varchar 类型
-
语法 :
varchar(L),L 为字符长度(最大 65535 字节,受表编码影响)。 -
特性:长度可变,实际占用空间为 "数据长度 + 1~3 字节(记录数据长度)",节省空间。
-
长度限制 :
- 总有效字节数为 65532(减去 1~3 字节的长度记录);
- 受编码影响:
- utf8 编码(1 字符 = 3 字节):最大 L = 65532 / 3 ≈ 21844;
- gbk 编码(1 字符 = 2 字节):最大 L = 65532 / 2 = 32766。
-
案例 :
sqlcreate table tt10(id int, name varchar(6)); -- 最多存6个字符 insert into tt10 values(100, 'hello'); -- 5个字母,正常 insert into tt10 values(100, '我爱你,中国'); -- 6个汉字,正常 create table tt11(name varchar(21845)) charset=utf8; -- 报错(超过21844)
4.3.3 char 和 varchar 比较

| 维度 | char(固定长度) | varchar(可变长度) |
|---|---|---|
| 空间占用 | 固定(可能浪费) | 按需分配(节省) |
| 效率 | 高(直接开辟固定空间) | 低(需计算长度并额外存储) |
| 适用场景 | 长度固定的数据(如身份证、手机号、MD5 值) | 长度可变的数据(如名字、地址) |
4.4 日期和时间类型
用于存储日期和时间,常用类型有date、datetime、timestamp。
| 类型 | 格式 | 范围 | 占用空间 | 特性 |
|---|---|---|---|---|
| date | 'yyyy-mm-dd' | 1000-01-01 ~ 9999-12-31 | 3 字节 | 仅存储日期 |
| datetime | 'yyyy-mm-dd HH:ii:ss' | 1000-01-01 00:00:00 ~ 9999-12-31 23:59:59 | 8 字节 | 存储日期 + 时间,需手动插入 |
| timestamp | 'yyyy-mm-dd HH:ii:ss' | 1970-01-01 00:00:01 ~ 2038-01-19 03:14:07 | 4 字节 | 存储日期 + 时间,默认自动插入 / 更新当前时间 |
案例:
sql
create table birthday(t1 date, t2 datetime, t3 timestamp);
-- 插入数据(仅指定t1和t2,t3自动补当前时间)
insert into birthday(t1,t2) values('1997-7-1','2008-8-8 12:1:1');
-- 更新数据(t3自动更新为当前时间)
update birthday set t1='2000-1-1';
select * from birthday;
-- 输出:t3显示更新时的当前时间
4.5 enum 和 set 类型
用于存储预定义的选项集合,enum 为 "单选",set 为 "多选"。
enum(枚举,单选)
-
语法 :
enum('选项1','选项2',...),最多 65535 个选项。 -
特性:实际存储选项对应的数字(1,2,3...),插入时可填选项值或对应数字(不建议用数字,可读性差)。
-
案例 :
sqlcreate table votes(gender enum('男','女')); -- 性别单选 insert into votes values('男'); -- 正常插入 insert into votes values(2); -- 2对应'女',插入成功
set(集合,多选)
-
语法 :
set('选项1','选项2',...),最多 64 个选项。 -
特性 :
set类型通过 "比特位对应选项" 的方式储存,支持同时选择多个选项(用逗号分隔)。 -
案例 :
sqlcreate table votes( username varchar(30), hobby set('登山','游泳','篮球','武术'), -- 爱好多选 gender enum('男','女') ); -- 插入数据(选择"登山"和"武术") insert into votes values('雷锋', '登山,武术', '男'); insert into votes values('雷锋', '7', '男');

set 类型的查询(find_in_set 函数)
直接用hobby='登山'无法查询到所有包含 "登山" 的记录,需用find_in_set(sub, str_list)函数:
-
功能:判断
sub是否在str_list(逗号分隔的字符串)中,存在返回下标,否则返回 0。 -
案例 :查询所有爱好包含 "登山" 的用户:
sqlselect * from votes where find_in_set('登山', hobby); -- 输出包含"登山"的所有记录(包括"登山,武术"等组合)