在 MySQL 数据库设计中,数据类型的选择直接影响存储效率、查询性能和数据准确性。选对数据类型能避免存储空间浪费、数据溢出、精度丢失等问题,而选错则可能导致系统隐患(如用 INT 存储手机号导致截断)。本文将全面拆解 MySQL 核心数据类型,结合实战案例讲解选型技巧,帮你从'能用'升级到'用好'。
CREATE TABLE tt5(gender bit(1));
INSERT INTO tt5 VALUES(0); -- 成功INSERT INTO tt5 VALUES(1); -- 成功INSERT INTO tt5 VALUES(2); -- 越界报错(bit(1) 仅支持 0/1)
2.1.1 TINYINT 类型测试
TINYINT 占用 1 字节,有符号范围 -128127,无符号范围 0255:
-- 1. 创建有符号 TINYINT 表CREATE TABLE test_tinyint1(age TINYINT);
-- 2. 插入合法值INSERT INTO test_tinyint1 VALUES(127); -- 成功(最大值)INSERT INTO test_tinyint1 VALUES(-128); -- 成功(最小值)-- 3. 插入越界值(报错)INSERT INTO test_tinyint1 VALUES(128); -- 报错:Out of range value for column 'age' at row 1-- 4. 创建无符号 TINYINT 表CREATE TABLE test_tinyint2(age TINYINT UNSIGNED);
-- 5. 插入无符号合法值INSERT INTO test_tinyint2 VALUES(255); -- 成功(无符号最大值)-- 6. 插入负数(无符号越界报错)INSERT INTO test_tinyint2 VALUES(-1); -- 报错:Out of range value for column 'age' at row 1
2.1.2 BIT 类型测试
BIT 存储位数据,默认 1 位(仅支持 0/1),位数 M 需≤64,查询时按 ASCII 码显示(易踩坑)。实际测试中有时也会显示为 16 进制,具体视客户端而定:
-- 1. 创建 BIT(1) 字段的表CREATE TABLE test_bit(gender BIT(1));
-- 2. 插入合法值(0/1)INSERT INTO test_bit VALUES(0); -- 成功INSERT INTO test_bit VALUES(1); -- 成功-- 3. 插入越界值(报错)INSERT INTO test_bit VALUES(2); -- 报错:Data truncation: Data too long for column 'gender' at row 1-- 4. 查询 BIT 字段(关键:直接查询显示 ASCII 字符,需转成数字)SELECT gender, bin(gender+0) FROM test_bit;
-- 1. INT 存储手机号(越界测试)CREATE TABLE test_int(phone INT);
INSERT INTO test_int VALUES(13800138000); -- 报错:Out of range value for column 'phone' at row 1(INT 最大值 2147483647 < 13800138000)-- 2. BIGINT 存储手机号(成功)CREATE TABLE test_bigint(phone BIGINT);
INSERT INTO test_bigint VALUES(13800138000); -- 成功SELECT*FROM test_bigint;
关键结论:FLOAT 是近似存储,存在精度丢失;DECIMAL 是精确存储,适合金额、税率等场景。float 表示的精度大约是 7 位,decimal 整数最大位置 m 为 65,支持小数最大位置 d 是 30,如果 d 被省略,默认位 0,如果 m 被省略,默认是 10。建议如果希望小数的精度高,推荐使用 DECIMAL。
2.2.2 DECIMAL 范围测试
CREATE TABLE test_decimal2(price DECIMAL(5,2));
-- 总长度 5,小数位 2 → 范围 -999.99~999.99INSERT INTO test_decimal2 VALUES(999.99); -- 成功INSERT INTO test_decimal2 VALUES(1000.00); -- 报错:Out of range value for column 'price' at row 1
-- UTF8 编码下,VARCHAR 最大字符数=65532/3≈21844(预留 1-3 字节存长度)CREATE TABLE test_varchar_limit1(name VARCHAR(21845)) CHARSET=utf8;
-- 报错:Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535.CREATE TABLE test_varchar_limit2(name VARCHAR(21844)) CHARSET=utf8;
-- 成功