【MySQL全面教学】MySQL数据类型详解Day2(2026年)

大家好,我是你们的数据库学习伙伴。今天是MySQL系列教程的第2天,我们将深入探讨MySQL的数据类型。选错数据类型可能会导致数据丢失、性能下降甚至系统崩溃,所以这一课非常重要!

文章目录


一、为什么数据类型很重要

1.1 一个真实的踩坑案例

在存储商品价格时使用 FLOAT 类型:

sql 复制代码
CREATE TABLE products (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(100),
    price FLOAT  -- 错误的选择!
);

当计算订单金额时,出现了这样的情况:

sql 复制代码
INSERT INTO products (name, price) VALUES ('iPhone 15', 5999.99);
SELECT * FROM products;
-- 结果:5999.989990234375

0.01元的误差,在财务系统中是不可接受的!这就是浮点数精度问题导致的悲剧。

1.2 选错数据类型的后果

问题类型 具体表现 影响程度
数据丢失 TINYINT存储大数导致溢出 严重
精度问题 FLOAT/DOUBLE存储金额 严重
性能下降 使用过大的数据类型 中等
存储浪费 VARCHAR(500)存短文本 轻微
兼容性问题 TIMESTAMP的2038年限制 严重

二、数值类型详解

2.1 整数类型

MySQL提供了5种整数类型,它们的区别主要在于取值范围和存储空间:

类型 存储空间 有符号范围 无符号范围 适用场景
TINYINT 1字节 -128 ~ 127 0 ~ 255 状态、布尔值
SMALLINT 2字节 -32768 ~ 32767 0 ~ 65535 小范围计数
MEDIUMINT 3字节 -8388608 ~ 8388607 0 ~ 16777215 中等范围ID
INT 4字节 -21亿 ~ 21亿 0 ~ 43亿 主键ID、计数
BIGINT 8字节 极大范围 极大范围 分布式ID、大数

经验之谈:

  • 状态字段用 TINYINT(如:0-禁用,1-启用)
  • 主键ID用 INT UNSIGNED AUTO_INCREMENT
  • 用户ID如果可能超过21亿,用 BIGINT
sql 复制代码
-- 用户表设计示例
CREATE TABLE users (
    id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    status TINYINT UNSIGNED DEFAULT 1 COMMENT '0-禁用 1-启用',
    age TINYINT UNSIGNED COMMENT '年龄,0-255足够',
    login_count INT UNSIGNED DEFAULT 0
);

2.2 浮点类型与定点类型

类型 存储空间 精度 适用场景 注意事项
FLOAT 4字节 约7位 科学计算 有精度损失
DOUBLE 8字节 约15位 科学计算 有精度损失
DECIMAL 变长 自定义 金额计算 精确计算

重点:DECIMAL用于金额

sql 复制代码
-- 正确的金额存储方式
CREATE TABLE orders (
    id INT PRIMARY KEY AUTO_INCREMENT,
    total_amount DECIMAL(10, 2) COMMENT '总金额,整数8位+小数2位',
    discount DECIMAL(10, 2) DEFAULT 0.00
);

-- DECIMAL(M, D) 说明:
-- M:总位数(精度),最大65
-- D:小数位数(标度),最大30
-- DECIMAL(10, 2) 可以存储:-99999999.99 到 99999999.99

踩坑提醒: 永远不要使用FLOAT或DOUBLE存储金额!银行、电商、支付系统必须使用DECIMAL。


三、字符串类型详解

3.1 CHAR vs VARCHAR

这是面试中最常问的问题之一:

特性 CHAR VARCHAR
存储方式 固定长度 变长
存储空间 始终占用定义长度 实际长度+1~2字节
性能 更快(无长度计算) 稍慢
适用场景 固定长度数据 变长数据
最大长度 255字符 65535字节
sql 复制代码
-- CHAR适合存储固定长度的数据
CREATE TABLE users (
    phone CHAR(11) COMMENT '手机号,固定11位',
    id_card CHAR(18) COMMENT '身份证号,固定18位',
    gender CHAR(1) COMMENT '性别 M/F'
);

-- VARCHAR适合存储变长数据
CREATE TABLE articles (
    title VARCHAR(200) COMMENT '标题,长度不固定',
    summary VARCHAR(500) COMMENT '摘要'
);

经验之谈:

  • 手机号、身份证号、固定编码用 CHAR
  • 用户名、标题、地址用 VARCHAR
  • 长度限制要合理,不要为了省事都设255

3.2 TEXT与BLOB类型

类型 最大长度 存储方式 适用场景
TINYTEXT 255字节 外部存储 短文本
TEXT 64KB 外部存储 文章内容
MEDIUMTEXT 16MB 外部存储 长文章
LONGTEXT 4GB 外部存储 大文本
TINYBLOB 255字节 外部存储 小二进制
BLOB 64KB 外部存储 图片、文件
MEDIUMBLOB 16MB 外部存储 较大文件
LONGBLOB 4GB 外部存储 大文件

踩坑提醒:

  • TEXT/BLOB类型不能设置默认值
  • 查询时不会加载到内存,性能较差
  • 大文件建议存对象存储(OSS/S3),数据库只存URL
sql 复制代码
-- 文章表设计
CREATE TABLE articles (
    id INT PRIMARY KEY AUTO_INCREMENT,
    title VARCHAR(200),
    content TEXT COMMENT '正文内容',
    cover_image VARCHAR(500) COMMENT '封面图URL,不是存图片本身'
);

四、日期时间类型详解

4.1 五种日期时间类型对比

类型 格式 范围 存储空间 适用场景
DATE YYYY-MM-DD 1000-01-01 ~ 9999-12-31 3字节 生日、纪念日
TIME HH:MM:SS -838:59:59 ~ 838:59:59 3字节 持续时间
YEAR YYYY 1901 ~ 2155 1字节 年份
DATETIME YYYY-MM-DD HH:MM:SS 1000-01-01 ~ 9999-12-31 8字节 通用时间
TIMESTAMP YYYY-MM-DD HH:MM:SS 1970-01-01 ~ 2038-01-19 4字节 记录时间戳
sql 复制代码
CREATE TABLE events (
    id INT PRIMARY KEY AUTO_INCREMENT,
    event_date DATE COMMENT '活动日期',
    start_time TIME COMMENT '开始时间',
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

4.2 踩坑:TIMESTAMP的2038年问题

这是MySQL中一个著名的时间炸弹!

TIMESTAMP使用4字节存储,最大只能表示到 2038-01-19 03:14:07 UTC

sql 复制代码
-- 这个插入在2038年后会失败!
INSERT INTO events (created_at) VALUES ('2040-01-01 00:00:00');
-- ERROR 1292 (22007): Incorrect datetime value

解决方案:

  1. 使用 DATETIME 代替 TIMESTAMP
  2. 升级到MySQL 8.0,使用 DATETIME(6) 支持微秒

经验之谈:

  • 记录创建/更新时间用 TIMESTAMP(自动时区转换)
  • 需要存储未来时间(如预约)用 DATETIME
  • 生日、历史日期用 DATE

五、JSON类型(MySQL 5.7+)

MySQL 5.7开始原生支持JSON类型,可以存储和查询JSON数据。

sql 复制代码
-- 存储商品规格(不同商品规格不同)
CREATE TABLE products (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(100),
    specs JSON COMMENT '商品规格,JSON格式'
);

-- 插入JSON数据
INSERT INTO products (name, specs) VALUES 
('iPhone 15', '{"color": "黑色", "storage": "256GB", "screen": "6.1英寸"}'),
('MacBook Pro', '{"color": "银色", "cpu": "M3", "ram": "16GB"}');

-- 查询JSON字段
SELECT * FROM products WHERE JSON_EXTRACT(specs, '$.color') = '黑色';
-- 或使用 -> 运算符
SELECT specs->>'$.storage' FROM products WHERE id = 1;

JSON类型的优势:

  • 自动验证JSON格式
  • 支持索引(通过虚拟列)
  • 支持JSON函数查询

经验之谈:

  • 适合存储不固定的属性(如商品规格、用户配置)
  • 不要滥用,固定字段还是建议用列存储
  • 频繁查询的JSON字段建议创建虚拟列索引

六、数据类型选择最佳实践

6.1 经验总结表

数据场景 推荐类型 说明
主键ID INT UNSIGNED / BIGINT 根据数据量选择
状态/枚举 TINYINT 0-禁用,1-启用
金额 DECIMAL(10,2) 精确计算
手机号 CHAR(11) 固定长度
邮箱 VARCHAR(100) 长度可变
短文本 VARCHAR(255) 标题、名称
长文本 TEXT 文章内容
日期 DATE 生日、纪念日
时间戳 TIMESTAMP/DATETIME 记录时间
JSON数据 JSON 灵活属性

6.2 设计原则

  1. 最小够用原则:选择满足需求的最小类型
  2. 精确优先原则:金额用DECIMAL,不用浮点数
  3. 固定优先原则:固定长度用CHAR,变长用VARCHAR
  4. 简单优先原则:能用简单类型不用复杂类型

七、面试高频考点

考点1:INT(11)的11是什么意思?

答案: INT(11)中的11只是显示宽度,与存储范围无关。INT始终占用4字节。

sql 复制代码
-- INT(11) 和 INT(3) 存储范围完全相同
-- 11只在配合 ZEROFILL 时有视觉效果
CREATE TABLE test (
    num1 INT(5) ZEROFILL,
    num2 INT
);
INSERT INTO test VALUES (123, 123);
-- num1显示:00123
-- num2显示:123

考点2:VARCHAR(255)和VARCHAR(100)的区别?

答案:

  • 存储长度小于255时,VARCHAR需要1字节存储长度;超过255需要2字节
  • VARCHAR(100)和VARCHAR(255)存储'hello'占用空间相同
  • 但VARCHAR(255)可能让开发者放松警惕,存储过长的数据
  • 建议:根据实际业务需求设置合理长度

考点3:CHAR和VARCHAR的区别?

答案:

  • CHAR固定长度,VARCHAR变长
  • CHAR性能稍好,VARCHAR节省空间
  • CHAR最大255字符,VARCHAR最大65535字节
  • 存储长度固定用CHAR(如手机号),变长用VARCHAR

考点4:为什么金额不能用FLOAT/DOUBLE?

答案: 浮点数使用二进制存储小数,无法精确表示某些十进制小数(如0.1),会导致精度丢失。财务计算必须使用DECIMAL。


八、总结

今天我们学习了MySQL的主要数据类型:

  1. 数值类型:TINYINT/INT/BIGINT用于整数,DECIMAL用于金额
  2. 字符串类型:CHAR固定长度,VARCHAR变长,TEXT存大文本
  3. 日期时间:DATE/DATETIME/TIMESTAMP各有适用场景
  4. JSON类型:灵活存储非结构化数据

记住三个原则:最小够用、精确优先、简单优先。


九、下一步预告

Day3:MySQL基础SQL语句

我们将学习:

  • DDL语句:CREATE、DROP、ALTER
  • DML语句:INSERT、UPDATE、DELETE
  • DQL语句:SELECT基础查询
  • 实战:创建电商订单系统相关表

十、参考资料

  1. MySQL 8.0官方文档 - 数据类型
  2. MySQL技术内幕:InnoDB存储引擎 - 数据存储

互动话题

你在工作中遇到过哪些数据类型相关的坑?欢迎在评论区分享:

  1. 你是否曾经用FLOAT存过金额?后来怎么解决的?
  2. 你们项目中主键ID用INT还是BIGINT?为什么?
  3. 对于TIMESTAMP的2038年问题,你们是怎么处理的?

点赞+收藏+关注,学习MySQL不迷路!我们Day3见!

相关推荐
一只fish5 小时前
Oracle官方文档翻译《Database Concepts 26ai》第10章-SQL
数据库·oracle
怒放吧德德5 小时前
JDK 版本一键切换工具(windows)
后端·shell
jnrjian5 小时前
export partition 的par file
数据库·oracle
空中海5 小时前
Redis知识图谱和回顾
数据库·redis·知识图谱
不甘先生5 小时前
PostgreSQL 数据库基础一览表
数据库·postgresql
爱上语文5 小时前
2026在线会议软件推荐:8款工具对比评测与多人协作选型指南
后端
DBdoctor官方5 小时前
2026 DBA实测推荐:5款数据库管理工具 监控、SQL审核、AI能力横评
数据库·sql·dba
小江的记录本5 小时前
【Java并发编程】锁机制:volatile:JMM内存模型、可见性/禁止指令重排、内存屏障、单例模式中的应用(附《思维导图》+《面试高频考点清单》)
java·后端·python·mysql·单例模式·面试·职场和发展
qq_196976175 小时前
硬核项目管理:Gemini境像站驱动的WBS自动分解、关键路径识别与风险登记册生成(国内免费镜像实测)
数据库