MySQL的常用数据类型

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. 日期时间类型(存时间:创建时间、更新时间、生日等)

核心常用DATETIMETIMESTAMPDATE/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 '商家经纬度' -- 存经纬度坐标

三、数据类型选型最佳实践(避坑核心,新手必看)

  1. 最小原则 :选能满足业务的最小数据类型(如年龄用TINYINT不用INT,手机号用CHAR(11)不用VARCHAR(255)),节省存储空间,提升查询效率;
  2. 精准原则 :金额/价格用DECIMAL不用FLOAT/DOUBLE,避免精度丢失;
  3. 字符串原则 :固定长度用CHAR ,可变长度用VARCHAR ,超长文本用TEXT,手机号/身份证用字符串不用数值类型(避免首位0丢失、超范围);
  4. 时间原则 :非时区需求用DATETIME不用TIMESTAMP,避免2038年溢出,创建/更新时间用自动填充语法;
  5. 主键原则 :主键优先用INT BIGINT AUTO_INCREMENT(自增主键),分布式场景用BIGINT(雪花ID),不用字符串作主键(查询慢);
  6. 避免大字段 :不把图片/视频直接存MySQL,存文件路径/云存储链接
  7. 非空原则 :尽量给字段设置默认值(如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 可多选的固定选项

总结

  1. MySQL数据类型按用途分8大类,核心常用3类数值(INT/DECIMAL)、字符串(CHAR/VARCHAR/TEXT)、日期时间(DATETIME),覆盖90%以上开发场景;
  2. 数值类型选最小精准 的(年龄TINYINT、金额DECIMAL),字符串类型按长度是否固定 选CHAR/VARCHAR,时间类型非时区需求优先DATETIME
  3. 经典必记写法:自增主键INT AUTO_INCREMENT、创建时间DATETIME DEFAULT CURRENT_TIMESTAMP、更新时间DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
  4. 选型核心原则:最小、精准、非空,避免用FLOAT存金额、INT存手机号、直接存二进制文件等经典坑;
  5. 特殊类型(ENUM/SET/BLOB)仅在对应小众场景使用,开发中优先用核心类型。
相关推荐
知我Deja_Vu10 小时前
redisCommonHelper.generateCode(“GROUP“),Redis 生成码方法
数据库·redis·缓存
寄存器漫游者10 小时前
Linux 线程间通信
数据库·算法
努力的lpp10 小时前
SQLMap CTF 常用命令全集
数据库·web安全·网络安全·sql注入
IvorySQL11 小时前
揭开 PostgreSQL 读取效率问题的真相
数据库·postgresql·开源
努力的lpp11 小时前
SQL 报错注入
数据库·sql·web安全·网络安全·sql注入
麦聪聊数据11 小时前
统一 Web SQL 平台如何收编企业内部的“野生数据看板”?
数据库·sql·低代码·微服务·架构
山峰哥11 小时前
吃透 SQL 优化:告别慢查询,解锁数据库高性能
服务器·数据库·sql·oracle·性能优化·编辑器
TDengine (老段)12 小时前
TDengine IDMP 数据可视化——散点图
大数据·数据库·物联网·信息可视化·时序数据库·tdengine·涛思数据
Project_Observer12 小时前
工时日志在项目进度管理中扮演着怎样的角色?
数据库·深度学习·机器学习
倔强的石头_12 小时前
kingbase备份与恢复实战(一)—— 备份体系、RPO-RTO与选型(Windows+ksql)
数据库