MySQL 数据类型完整学习笔记
一、数据类型总览
MySQL数据类型分为五大类:
- 数值类型:整型、bit位类型
- 小数类型:float、decimal
- 字符串类型:char、varchar
- 日期时间类型:date、datetime、timestamp
- 枚举与集合:enum、set
二、数值类型
2.1 整型(TINYINT、SMALLINT、INT、BIGINT)
可以携带UNSIGNED关键字代表无符号,默认有符号。
| 类型 | 字节 | 有符号范围 | 无符号范围 |
|---|---|---|---|
| TINYINT | 1字节 | -128 ~ 127 | 0 ~ 255 |
| SMALLINT | 2字节 | -32768 ~ 32767 | 0 ~ 65535 |
| INT | 4字节 | -2¹⁰‑³ ~ 2³¹‑1 | 0 ~ 4294967295 |
| BIGINT | 8字节 | -2⁶³ ~ 2⁶³‑1 | 0 ~ 18446744073709551615 |
越界测试:插入超出范围的数据会直接报错
Out of range value。
sql
create table tt1(num tinyint);
insert into tt1 values(128); -- 超出有符号tinyint上限,报错
无符号示例:
sql
create table tt2(num tinyint unsigned);
insert into tt2 values(-1); -- 无符号不能存负数,报错
insert into tt2 values(255); -- 合法
建议:尽量少用UNSIGNED。如果数值存不下,直接升级为更大的类型(int→bigint),不要单纯依赖无符号扩展范围。
2.2 bit位类型
语法:bit[(M)],M代表位数,取值1‑64,省略M默认是1。
bit存储二进制位,查询显示为ASCII字符,不是数字。
sql
create table tt4 ( id int, a bit(8));
insert into tt4 values(10, 65);
select * from tt4; -- a=65,显示为字符'A'
适用场景:只存0/1状态,使用bit(1)节省存储空间。
sql
create table tt5(gender bit(1));
insert into tt5 values(0);
insert into tt5 values(1);
insert into tt5 values(2); --越界报错
三、小数类型
3.1 float 浮点数
语法:float(M,D) [unsigned]
- M:总显示长度,D:小数位数,占用4字节
- 存储会自动四舍五入;float精度大约7位,存在精度丢失,不适合金额。
示例:float(4,2),有符号范围 -99.99 ~ 99.99
sql
create table tt6(id int, salary float(4,2));
insert into tt6 values(101, -99.991); --自动四舍五入变成-99.99
加unsigned后不能存负数,负数会触发警告。
3.2 decimal 定点数
语法:decimal(M,D) [unsigned]
- M总长度,D小数位数;最大M=65,D最大30,占用8字节。
- 精度高,不会丢失精度,金额、财务数据优先选用decimal。
对比float与decimal精度差异:
sql
create table tt8 ( id int, salary float(10,8), salary2 decimal(10,8));
insert into tt8 values(100,23.12345612, 23.12345612);
float会出现精度偏差,decimal保存原始小数。
选型:普通小数可以float;钱、财务计算必须用decimal。
四、字符串类型 char vs varchar
4.1 char 固定长度字符串
语法:char(L),L为字符数,最大255字符。
固定开辟L个字符空间,数据不足也占满空间。读写速度快,浪费存储空间。
sql
create table tt9(id int, name char(2));
insert into tt9 values(101, '中国'); -- 可以存放2个汉字
4.2 varchar可变长度字符串
语法:varchar(L),L代表字符数。
总字节上限65535字节,其中1‑3字节用来记录数据长度。
- utf8编码:一个字符占3字节,varchar最大字符数约
21844 - gbk编码:一个字符占2字节,varchar最大字符数约
32766
按需分配空间,节省磁盘,但是读写效率略低于char。
sql
create table tt10(id int ,name varchar(6));
insert into tt10 values(100, '我爱你,中国');
char 和 varchar选型对比
| 类型 | 特点 | 适用场景 |
|---|---|---|
| char(L) | 定长,空间浪费,效率高 | 长度固定:手机号、身份证、MD5密码 |
| varchar(L) | 变长,节省空间,效率略低 | 长度波动:用户名、地址、简介 |
char(4)存入'A',仍然占用4字符空间;varchar(4)存入'A'只占用1字符+记录字节。
五、日期时间类型
| 类型 | 格式 | 占用字节 | 说明 |
|---|---|---|---|
| date | yyyy‑mm‑dd |
3字节 | 只保存日期 |
| datetime | yyyy‑mm‑dd HH:ii:ss |
8字节 | 日期+时间,范围1000‑9999年 |
| timestamp | yyyy‑mm‑dd HH:ii:ss |
4字节 | 时间戳,起始1970‑01‑01;插入/更新会自动填充当前时间 |
示例:
sql
create table birthday (t1 date, t2 datetime, t3 timestamp);
insert into birthday(t1,t2) values('1997-7-1','2008-8-8 12:1:1');
timestamp特性:新增、更新该行数据时,会自动刷新为当前系统时间。
六、enum枚举 和 set集合
6.1 enum 枚举(单选)
enum('选项1','选项2','选项3')
只能选择其中一个值,底层存储数字,不建议直接写数字插入,可读性差。
sql
gender enum('男','女')
6.2 set集合(多选)
set('选项1','选项2','选项3')
可以多选多个值,底层按比特位存储。
❗注意:普通
where hobby='登山'只能匹配恰好只有"登山"的记录,无法匹配同时包含登山+其他爱好的数据。
查询集合包含某个值,要用find_in_set()函数
sql
-- find_in_set(要查找的值, 集合字段)
select * from votes where find_in_set('登山', hobby);
find_in_set(sub,str_list):找到返回位置下标,找不到返回0。
完整建表演示:
sql
create table votes(
username varchar(30),
hobby set('登山','游泳','篮球','武术'),
gender enum('男','女')
);
insert into votes values('雷锋', '登山,武术', '男');
七、数据类型选型总结
- 整型:根据业务范围选择,尽量避免unsigned,不够用直接升级更大类型。
- 小数:普通展示用float;金额财务必须使用decimal。
- 字符串:定长用char;长短不一用varchar,注意编码带来最大字符限制。
- 时间:只存日期用date;完整时间用datetime;timestamp有自动更新时间特性。
- enum用于单选,set用于多选;集合查询记得使用
find_in_set。