一文通关 MySQL 数据类型,打好高性能数据库的第一战!

一文通关 MySQL 数据类型,打好高性能数据库的第一战!

数据类型选错,是MySQL性能杀手Top3之一(其他两个是索引乱加 + SELECT * 成习惯)。

2026年MySQL主流仍是8.4 LTS系列(创新分支已到9.x,但生产稳扎稳打还是8.4),数据类型本身变化不大,但“最小合适 + 理解存储代价 + 索引友好” 这三条原则比任何时候都更重要。

我们直接用最务实的结构来过一遍:分类 + 范围 + 存储代价 + 推荐场景 + 常见雷区。

1. 数值类型(最常用、最影响性能的一类)

类型占用字节有符号范围无符号范围推荐场景(2026主流)常见坑 / 注意点
TINYINT1-128 ~ 1270 ~ 255年龄、状态码、性别、布尔(0/1)别用TINYINT存“可能超过255”的东西
SMALLINT2-32,768 ~ 32,7670 ~ 65,535城市ID、小订单量、库存少量
MEDIUMINT3-8,388,608 ~ 8,388,6070 ~ 16,777,215中等基数ID(如文章ID早期阶段)很少用,跳过直接用INT
INT / INTEGER4-2^31 ~ 2^31-10 ~ 2^32-1用户ID、订单ID、商品ID(绝大多数业务首选)主键/外键默认用INT UNSIGNED
BIGINT8-2^63 ~ 2^63-10 ~ 2^64-1雪花ID、支付流水号、点赞数亿级、时间戳(ms)别滥用,4字节INT够用就别上8字节
DECIMAL / NUMERIC变长精度由M,D决定金额、汇率、科学计算绝对不能用FLOAT/DOUBLEDECIMAL(18,4) 常见电商金额
FLOAT / DOUBLE4 / 8约6/15位有效数字科学计算、坐标(不要求绝对精确)生产禁用用于金融/金额,精度丢失

2026核心建议

  • 主键/外键/高频WHERE/JOIN字段 → INT UNSIGNEDBIGINT UNSIGNED(自增/雪花)
  • 年龄/状态/枚举值 → TINYINT UNSIGNED
  • 钱相关 → DECIMAL(15,2) ~ DECIMAL(18,4)(视业务最大值)
  • 永远别用FLOAT/DOUBLE存钱(哪怕你加了四舍五入也容易出1分钱bug)

2. 字符串类型(空间 & 索引开销大户)

类型存储方式最大长度适用场景性能建议 & 雷区
CHAR(n)固定长度,补空格0~255固定长度码(如身份证前6位、省份码、性别M/F)适合真正固定长;短数据浪费空间
VARCHAR(n)变长 + 1~2字节长度前缀0~65,535绝大多数文本字段(姓名、地址、标题)主流首选;n设真实最大值,别习惯255/500
TINYTEXT变长255极短文本很少用
TEXT变长65,535文章正文、评论(较短)不能建普通索引(前缀索引可)
MEDIUMTEXT变长16MB长文章、富文本
LONGTEXT变长4GB超大内容(如日志、爬虫页面)慎用,IO代价高

关键避坑

  • VARCHAR(255) 是坏习惯 → 改成VARCHAR(50)/VARCHAR(100)/VARCHAR(191)(191是utf8mb4单列索引最大字节限制)
  • 带emoji/全球字符 → 必须用utf8mb4字符集,别用utf8(utf8只支持3字节,emoji4字节会报错)
  • 超过500字符的文本字段 → 考虑放OSS + 只存URL

3. 日期 & 时间类型(排序 & 范围查询最友好)

类型占用字节格式 / 范围推荐场景注意事项 & 推荐写法
DATE3‘1000-01-01’ ~ ‘9999-12-31’生日、注册日
DATETIME5~8‘1000-01-01 00:00:00’ ~ ‘9999-12-31 …’创建时间、更新时间、订单时间(主流)DATETIME DEFAULT CURRENT_TIMESTAMP
TIMESTAMP4‘1970-01-01 00:00:01’ UTC ~ 2038自动更新时间戳(旧项目多见)2038年问题;MySQL 8.0+支持到2106
TIME3‘-838:59:59’ ~ ‘838:59:59’时长、营业时间
YEAR11901 ~ 2155出生年份极少用

2026推荐组合

created_at  DATETIME(0) DEFAULT CURRENT_TIMESTAMP,
updated_at  DATETIME(0) DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
deleted_at  DATETIME(0) DEFAULT NULL COMMENT '软删除'

4. 其他常用 / 新兴类型

  • JSON(MySQL 5.7+):文档存储、配置、扩展字段。支持JSON路径索引、函数(JSON_EXTRACT等)
  • 推荐:热点读多 → 抽成结构化字段;偶尔读 → JSON
  • ENUM / SET:空间省,但改值要ALTER TABLE,慎用(2026主流建议用TINYINT + 代码映射代替)
  • BOOLEAN:实际是TINYINT(1),0/1存true/false
  • VECTOR(MySQL 9.0+创新分支):AI嵌入向量(embedding),支持距离计算(欧氏/余弦等)
  • 生产用得少,HeatWave或专用向量DB更常见

5. 一张终极选择速查表(直接抄)

业务字段推荐类型为什么 / 替代方案
主键IDBIGINT UNSIGNED雪花ID安全;或INT UNSIGNED(小系统)
用户名/昵称VARCHAR(30)~VARCHAR(60)utf8mb4
手机号VARCHAR(20)考虑+86等前缀
金额DECIMAL(12,2) 或 DECIMAL(18,4)精确无丢失
创建/更新时间DATETIME(0)支持毫秒用DATETIME(3)
状态TINYINT UNSIGNED0=待支付 1=已支付 …
性别TINYINT(1) 或 ENUM(‘男’,’女’,’其他’)TINYINT更灵活
IP地址VARCHAR(45)支持IPv6
文章内容MEDIUMTEXT 或 TEXT长文本放外部存储

6. 性能第一定律(背下来)

“越小越好,但别溢出” + “索引友好” + “utf8mb4统一”

  • 选最小能装下的类型 → 少占空间 → 索引更小 → 内存命中更高 → IO更少
  • VARCHAR(n) 的n要真实业务最大值(别255默认)
  • 所有表统一utf8mb4_unicode_520_ci(或 utf8mb4_0900_ai_ci)
  • 金额/坐标/科学计数 → 坚决不用FLOAT/DOUBLE
  • 主键别用UUID(乱序插入页分裂),用自增或有序雪花

你现在建表时最纠结哪个字段的类型?
或者你有一个具体的业务表(比如订单表、用户表),贴出当前建表语句,我可以帮你直接优化数据类型 + 指出潜在性能雷。

文章已创建 4915

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部