📄 一句话概括
数值类型分两派:整数派(INT)省地方、算得准;小数派里又分精确派(DECIMAL,给钱用)和近似派(FLOAT/DOUBLE,给科学计算用)——钱永远用 DECIMAL,这是本章最重要的一个选择。
📝 本节和前面几节的关系
上一节(4-1)说清了「类型是第一道防线」,从本节起按家族逐个过。数值是最常用的家族:第三章贯穿示例表 students 的 id 用了 INT、score 用了 DECIMAL——本节讲清这两个为什么这么选,以及 FLOAT/DOUBLE 为什么不能用来存钱。
一、整数:INT 家族
INT 存不带小数点的整数(约 ±21 亿)。 MySQL 还有更小/更大的档位:
| 类型 | 范围 | 典型用途 |
|---|---|---|
TINYINT |
-128 ~ 127 | 年龄、开关量 |
INT |
约 ±21 亿 | 一般编号、数量 |
BIGINT |
约 ±922 京 | 订单号、访问量 |
原则:够用就好,越小越省。一张亿级大表,每行省 3 字节就是省 3 亿字节。
二、精确小数:DECIMAL
DECIMAL(总位数, 小数位) —— 十进制精确存储,算多少是多少:
price DECIMAL(6,2) -- 最大 9999.99,精确到分
为什么钱必须用它?看 4.4 节的对比实验。
三、近似小数:FLOAT 与 DOUBLE
FLOAT(4 字节)/ DOUBLE(8 字节)用二进制近似存小数,胜在快、省,败在不精确。适合:
- 科学计算(误差不敏感)
- 坐标、百分比统计(差一点点无所谓)
不适合:账户余额、订单金额——差一分钱都是事故。
四、动手 Demo:0.1 的陷阱
CREATE TABLE money_test (
f FLOAT,
d DECIMAL(10,2)
);
INSERT INTO money_test VALUES (0.1, 0.1);
INSERT INTO money_test VALUES (0.2, 0.2);
SELECT SUM(f) AS 浮点合计, SUM(d) AS 精确合计 FROM money_test;
结果(经典二进制浮点误差):
浮点合计 精确合计
0.30000000447034836 0.30
同一笔账,FLOAT 算出了 0.3000000044...,DECIMAL 干干净净给出 0.30。这就是钱用 DECIMAL 的理由。
五、30 秒实验
建 price FLOAT 和 price DECIMAL(6,2) 两个表,各塞 1234567.89,再查出来对比——FLOAT 可能已经悄悄变了值(超出 7 位有效数字),DECIMAL 纹丝不动。
六、常见误区
- 「DOUBLE 比 DECIMAL 大,选它准没错」:大的是范围不是精度;
DOUBLE的 0.1 依旧不等于精确 0.1 - 「DECIMAL(10,2) 能存 10 位数字」:是总位数 10 位、其中 2 位小数,整数部分最多 8 位
自测三问
1. 存工资用什么类型?(DECIMAL,绝不用 FLOAT/DOUBLE) 2. `DECIMAL(6,2)` 的含义?(总 6 位、小数 2 位,最大 9999.99) 3. FLOAT/DOUBLE 适合什么场景?(误差不敏感的科学计算、统计,不适合钱)- ☐ 下一节(4-3 CHAR、VARCHAR、TEXT-处理字符串的数据类型)
相关笔记
- 数据类型-指定可保存的数据类型 —— 上一节:类型是第一道防线
- CREATE TABLE、DROP TABLE-创建和删除表 —— students 表里 score 选 DECIMAL 的原因
- 🗄️ 数据库基础 · 索引 —— 全课路线图