MySQL会根据存储的数据类型(数字/文本/时间/二进制等) 把数据类型分成8大类,核心常用的是数值、字符串、日期时间三类(开发中90%以上的场景都会用到),其余类型为特殊场景使用。
下面按「常用程度从高到低 」分类讲解,每个类型会说明用途、语法、适用场景 ,并标注开发推荐用法 ,同时补充选型最佳实践,新手能直接根据业务场景选对应类型,避免踩坑(比如用INT存手机号、FLOAT存金额的经典错误)。
一、核心常用类型(必掌握,覆盖90%业务场景)
1. 数值类型(存数字:主键ID、金额、数量、年龄等)
分整数 和小数 两大类,重点是根据数值范围选最小的类型(节省存储空间,提升查询效率)。
(1)整数类型(精准无精度丢失,最常用)
| 类型 | 字节 | 取值范围 | 推荐适用场景 |
|---|---|---|---|
TINYINT |
1 | -128 ~ 127(无符号0~255) | 状态值(0/1/2)、性别、排序值 |
SMALLINT |
2 | -32768 ~ 32767(无符号0~65535) | 小范围计数(如商品库存、年级) |
INT |
4 | -21亿 ~ 21亿(无符号0~42亿) | 主键ID、用户ID、订单号(常用) |
BIGINT |
8 | 极大范围(-9e18 ~ 9e18) | 超大范围ID(如分布式主键、雪花ID) |
关键用法:
- 无符号数:加
UNSIGNED(如TINYINT UNSIGNED),适合非负数(如年龄、库存); - 自增主键:
INT PRIMARY KEY AUTO_INCREMENT(开发中最常用的主键写法); - ❌ 避坑:不要用INT存手机号(手机号11位超INT无符号最大值42亿,且首位0会丢失),用字符串存。
示例:
sql
id INT PRIMARY KEY AUTO_INCREMENT, -- 主键ID(推荐)
status TINYINT UNSIGNED DEFAULT 0, -- 订单状态(0-未支付,1-已支付)
age TINYINT UNSIGNED, -- 年龄(0-255足够)
(2)小数类型(存金额、价格、百分比等,需精准无误差)
核心避坑 :不要用FLOAT/DOUBLE存金额 (浮点型有精度丢失,比如0.1+0.2≠0.3),开发中只推荐DECIMAL(定点型,精准无误差)。
| 类型 | 特点 | 语法 | 推荐适用场景 |
|---|---|---|---|
DECIMAL(M,D) |
精准定点型,无精度丢失 | M=总位数,D=小数位 | 金额、价格、税率 |
FLOAT |
单精度浮点,有精度丢失 | 不推荐 | 非精准计算(如坐标) |
DOUBLE |
双精度浮点,有精度丢失 | 不推荐 | 非精准计算(如评分) |
DECIMAL推荐用法:
- 金额场景:
DECIMAL(10,2)(总位数10,小数2位,可存0.00~99999999.99,满足大部分业务); - 百分比场景:
DECIMAL(5,2)(如36.50%)。
示例:
sql
amount DECIMAL(10,2) COMMENT '订单金额(元)', -- 推荐
discount DECIMAL(5,2) DEFAULT 10.00 COMMENT '折扣(如9.50=95折)'
2. 字符串类型(存文本:姓名、手机号、地址、备注等)
分定长 和变长 ,核心区别:定长CHAR查询快,变长VARCHAR省空间 ,开发中VARCHAR最常用。
| 类型 | 特点 | 适用场景 |
|---|---|---|
CHAR(n) |
定长,n=1~255,不足补空格 | 固定长度文本(如身份证、手机号、性别) |
VARCHAR(n) |
变长,n=1~65535,按实际存储 | 可变长度文本(姓名、地址、备注) |
TEXT |
长文本,最大65535字符 | 超长文本(如文章内容、商品描述) |
LONGTEXT |
极长文本,最大4G字符 | 超大文本(如日志、富文本内容) |
关键选型技巧:
- 固定长度用CHAR:比如手机号
CHAR(11)、身份证CHAR(18)(查询比VARCHAR快); - 可变长度用VARCHAR:比如姓名
VARCHAR(20)、地址VARCHAR(255); - 超长文本用TEXT/LONGTEXT:注意TEXT类型不能设置默认值;
- ❌ 避坑:VARCHAR(n)的
n是字符数(不是字节数),utf8mb4编码下1个中文字符占3~4字节,无需考虑字节数。
示例:
sql
name VARCHAR(20) NOT NULL, -- 姓名(可变长度)
phone CHAR(11) NOT NULL, -- 手机号(固定11位,推荐CHAR)
id_card CHAR(18) COMMENT '身份证号(固定18位)',
address VARCHAR(255) DEFAULT '' COMMENT '地址',
content TEXT COMMENT '文章内容(超长文本)'
3. 日期时间类型(存时间:创建时间、更新时间、生日等)
核心常用DATETIME和TIMESTAMP,DATE/TIME/YEAR为辅助类型,开发中DATETIME最通用。
| 类型 | 字节 | 取值范围 | 时区感知 | 推荐适用场景 |
|---|---|---|---|---|
DATETIME |
8 | 1000-01-01 ~ 9999-12-31 | 否 | 创建时间、更新时间、订单时间(通用) |
TIMESTAMP |
4 | 1970-01-01 ~ 2038-01-19 | 是 | 需时区同步的时间(如跨境业务) |
DATE |
3 | 只存年月日(如生日、入职日期) | 否 | 生日、商品上架日期 |
TIME |
3 | 只存时分秒(如上课时间) | 否 | 具体时间点(无日期) |
YEAR |
1 | 只存年份(如2024) | 否 | 仅需年份的场景(如毕业年份) |
开发高频用法(必记):
- 创建时间:
DATETIME DEFAULT CURRENT_TIMESTAMP(插入数据时自动填充当前时间); - 更新时间:
DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP(插入/更新数据时自动刷新为当前时间); - ❌ 避坑:
TIMESTAMP有2038年溢出问题,非时区需求优先用DATETIME。
示例(开发中最经典的时间字段写法):
sql
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后更新时间',
birthday DATE COMMENT '生日(只存年月日)'
二、特殊类型(小众场景使用,了解即可)
1. 枚举类型(ENUM)------ 固定可选值的单值选择
适合值为固定几个选项 的场景(如性别、订单状态),优点是限制取值范围、节省存储空间 ,语法:ENUM('值1','值2','值3')。
示例:
sql
gender ENUM('男','女','未知') DEFAULT '未知' COMMENT '性别',
order_status ENUM('未支付','已支付','已取消') DEFAULT '未支付' COMMENT '订单状态'
注意 :ENUM的取值是字符串,但底层按数字存储,查询时直接用字符串即可。
2. 集合类型(SET)------ 固定可选值的多值选择
适合一个字段取多个值 的场景(如用户爱好、商品标签),语法:SET('值1','值2','值3'),多个值用逗号分隔 。
示例:
sql
hobby SET('篮球','足球','读书','旅游') DEFAULT '' COMMENT '用户爱好(可多选)'
-- 插入时多选:INSERT INTO user (hobby) VALUES ('篮球,读书');
注意:SET的可选值最多64个,底层按位图存储,查询效率高。
3. 二进制类型(BLOB/LOB)------ 存二进制数据
适合存图片、视频、文件 等二进制数据,开发中不推荐直接存MySQL (会让表体积过大,查询变慢),推荐存文件路径/OSS链接,仅作了解:
| 类型 | 特点 | 适用场景 |
|---|---|---|
BLOB |
二进制大对象 | 小文件(如头像) |
MEDIUMBLOB |
中等二进制对象 | 中等文件 |
LONGBLOB |
超大二进制对象 | 大文件 |
4. 空间类型(GEOMETRY/POINT)------ 存地理空间数据
适合存经纬度、坐标、地理区域 等数据(如外卖商家位置、打车起点),需配合MySQL空间函数使用,小众场景:
示例:
sql
location POINT COMMENT '商家经纬度' -- 存经纬度坐标
三、数据类型选型最佳实践(避坑核心,新手必看)
- 最小原则 :选能满足业务的最小数据类型(如年龄用TINYINT不用INT,手机号用CHAR(11)不用VARCHAR(255)),节省存储空间,提升查询效率;
- 精准原则 :金额/价格用DECIMAL不用FLOAT/DOUBLE,避免精度丢失;
- 字符串原则 :固定长度用CHAR ,可变长度用VARCHAR ,超长文本用TEXT,手机号/身份证用字符串不用数值类型(避免首位0丢失、超范围);
- 时间原则 :非时区需求用DATETIME不用TIMESTAMP,避免2038年溢出,创建/更新时间用自动填充语法;
- 主键原则 :主键优先用INT BIGINT AUTO_INCREMENT(自增主键),分布式场景用BIGINT(雪花ID),不用字符串作主键(查询慢);
- 避免大字段 :不把图片/视频直接存MySQL,存文件路径/云存储链接;
- 非空原则 :尽量给字段设置默认值(如VARCHAR默认'',TINYINT默认0),避免NULL值(NULL会增加查询复杂度,部分索引不支持NULL)。
四、高频业务场景类型选型参考(直接套用)
| 业务字段 | 推荐数据类型 | 备注 |
|---|---|---|
| 主键ID | INT/BIGINT AUTO_INCREMENT | 常规用INT,分布式用BIGINT |
| 姓名/昵称 | VARCHAR(20)/VARCHAR(30) | 避免过长 |
| 手机号 | CHAR(11) | 固定11位,查询快 |
| 身份证号 | CHAR(18) | 固定18位 |
| 金额/价格 | DECIMAL(10,2) | 精准无误差 |
| 年龄 | TINYINT UNSIGNED | 0-255足够 |
| 状态/类型 | TINYINT UNSIGNED/ENUM | 简单状态用TINYINT,固定选项用ENUM |
| 创建/更新时间 | DATETIME + 自动填充 | 开发中经典写法 |
| 地址/备注 | VARCHAR(255) | 超长用TEXT |
| 爱好/标签 | SET | 可多选的固定选项 |
总结
- MySQL数据类型按用途分8大类,核心常用3类 :数值(INT/DECIMAL)、字符串(CHAR/VARCHAR/TEXT)、日期时间(DATETIME),覆盖90%以上开发场景;
- 数值类型选最小精准 的(年龄TINYINT、金额DECIMAL),字符串类型按长度是否固定 选CHAR/VARCHAR,时间类型非时区需求优先DATETIME;
- 经典必记写法:自增主键
INT AUTO_INCREMENT、创建时间DATETIME DEFAULT CURRENT_TIMESTAMP、更新时间DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP; - 选型核心原则:最小、精准、非空,避免用FLOAT存金额、INT存手机号、直接存二进制文件等经典坑;
- 特殊类型(ENUM/SET/BLOB)仅在对应小众场景使用,开发中优先用核心类型。