🗄️ 第四章 管理数据-避免非法数据的功能
📄 一句话概括

数值类型分两派:整数派(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 纹丝不动。

六、常见误区

自测三问 1. 存工资用什么类型?(DECIMAL,绝不用 FLOAT/DOUBLE) 2. `DECIMAL(6,2)` 的含义?(总 6 位、小数 2 位,最大 9999.99) 3. FLOAT/DOUBLE 适合什么场景?(误差不敏感的科学计算、统计,不适合钱)

相关笔记