大家好,我是极光。今天给大家带来一篇MySQL整数类型的深度解析,看完这篇文章,你将彻底明白如何为业务场景选择最合适的整数类型,避免常见的"类型选择恐惧症"!
🔍 为什么整数类型选择如此重要?真实案例:数据类型错误引发的血泪史
案例1:某社交平台使用TINYINT存储用户ID,当用户量突破127时系统直接崩溃,紧急停机6小时迁移数据!
案例2:电商平台用INT存储订单金额(单位:分),双11大促时出现金额溢出,导致财务对账出现百万元差异!
这些惨痛教训告诉我们:整数类型选择绝非小事!
整数类型选择不当会导致: ✅ 存储空间浪费 ✅ 查询性能下降 ✅ 数据溢出风险 ✅ 后期扩展困难
📊 MySQL五大整数类型对比表
类型 | 存储空间 | 有符号范围 | 无符号范围 | 适用场景 | 选型建议星级 |
---|---|---|---|---|---|
TINYINT | 1字节 | -128~127 | 0~255 | 状态码、布尔值 | ⭐⭐⭐⭐ |
SMALLINT | 2字节 | -32768~32767 | 0~65535 | 年份、小计数器 | ⭐⭐⭐ |
MEDIUMINT | 3字节 | -800万~800万 | 0~1600万 | 中型用户系统 | ⭐⭐ |
INT | 4字节 | -21亿~21亿 | 0~42亿 | 用户ID、订单号 | ⭐⭐⭐⭐⭐ |
BIGINT | 8字节 | -900亿亿~900亿亿 | 0~1800亿亿 | 分布式ID、大金额 | ⭐⭐⭐⭐ |
💡 极光点评:INT是大多数场景的"万金油"选择,但不要无脑用BIGINT!
🚀 五大实战应用场景解析
1️⃣ TINYINT - 小而美的选择
典型场景:
用户状态(1=活跃,0=冻结)
性别标识(0=未知,1=男,2=女)
是否删除的软标记
-- 最佳实践
CREATE TABLE user_status (
is_vip TINYINT(1) DEFAULT 0 COMMENT '0=普通用户,1=VIP',
is_deleted TINYINT(1) DEFAULT 0 COMMENT '0=未删除,1=已删除'
);
2️⃣ SMALLINT - 恰到好处的中间派
典型场景:
商品类目ID(适合类目数<6万的中小电商)
用户年龄存储(0-120岁完全够用)
年份存储(1900-2155年)
-- 电商类目案例
CREATE TABLE product_category (
cat_id SMALLINT UNSIGNED AUTO_INCREMENT,
year SMALLINT COMMENT '生产年份',
PRIMARY KEY(cat_id)
);
3️⃣ INT - 中流砥柱的王者
典型场景:
用户ID(支持42亿用户完全够用)
订单编号(绝大多数电商平台首选)
文章阅读量计数
案例1:用户系统设计
错误做法:
CREATE TABLE users (
id TINYINT UNSIGNED AUTO_INCREMENT, -- 最多255个用户!
username VARCHAR(50)
);
正确方案:
CREATE TABLE users (
id INT UNSIGNED AUTO_INCREMENT, -- 支持42亿用户
age TINYINT UNSIGNED, -- 年龄0-255足够
status TINYINT(1) DEFAULT 0, -- 0=正常,1=冻结
PRIMARY KEY(id)
) ENGINE=InnoDB;
案例2:电商订单系统
错误做法:
CREATE TABLE orders (
order_id MEDIUMINT UNSIGNED, -- 最多1600万订单
amount INT -- 金额可能溢出
);
正确方案:
CREATE TABLE orders (
order_id INT UNSIGNED AUTO_INCREMENT, -- 支持42亿订单
amount BIGINT COMMENT '单位为分', -- 大额交易防溢出
user_id INT UNSIGNED,
PRIMARY KEY(order_id)
);
💎 选型黄金法则
- 空间最优原则:能用1字节就不用2字节
- 无符号优先:不需要负数就加UNSIGNED
- 扩展性原则:用户ID即使用户少也要用INT
- 性能平衡点:主键在32位系统用INT性能最佳
❌ 常见踩坑案例
- 用TINYINT存用户ID → 用户量破百就崩
- 用INT存手机号 → 溢出且查询性能差
- 无脑用BIGINT → 浪费50%存储空间
- 忘记加UNSIGNED → 白丢一半取值范围
📚 延伸学习
想深入了解MySQL数据类型优化,推荐阅读:
- 《高性能MySQL》第4章数据类型优化
- MySQL官方文档: