一、数值类型
MySQL 的数值类型体系比较丰富,涵盖了整数和浮点数。在实际开发中,选对类型不仅能节省存储空间,还能提升查询效率。
1.1 tinyint 类型
tinyint 占用 1 个字节,有符号范围是 -128 到 127。我们直接通过建表测试一下它的极限值:
CREATE TABLE test_tinyint (num TINYINT);
INSERT INTO test_tinyint VALUES (-128), (127);
如果尝试插入超出范围的值,MySQL 会直接报错拦截。另外,tinyint 后面可以跟一个可选项 unsigned,代表无符号。加上这个属性后,范围就变为了 0 到 255,常用于状态标识或年龄等不需要负数的场景。
1.2 bit 类型
bit(M) 表示 M 位二进制数,如果不传 M,默认值为 1。这里有个小坑需要注意:bit 字段在显示时是按照 ASCII 码对应的值显示的,并不会直接显示数字。
比如插入 65,查出来就是大写字母 'A'。如果想看纯数字效果,建议设置 M=1 或者在应用层做转换。同样,如果插入的数值超出了比特位所能表示的最大值,数据库也会拦截。
二、小数类型
数值类型讲完了,下面进入小数类型。这里有两个容易混淆的类型:float 和 decimal。
2.1 float 类型
float 是浮点数类型,定义时需要传入两个参数:M(总位数)和 d(小数位数)。
CREATE TABLE test_float (salary FLOAT(4,2));
这里表示范围大约是 -99.99 到 99.99。如果在范围内但小数位超过 2 位,MySQL 会进行四舍五入处理。不过要注意,float 存在精度损失问题,大约只有 7 位有效数字,超过这个范围数据就不准了。
2.2 decimal 类型
decimal 和 float 类似,也是定点数,但精度更高。对于金额计算这种对精度要求严格的场景,必须使用 decimal。
CREATE TABLE test_decimal (price DECIMAL(10,2));
对比 float,decimal 能完全保留插入的数据,不会出现精度丢失。整数的最大位数 m 为 65,支持小数最大位数 d 是 30。
三、字符串类型
字符串类型分为定长和变长两种,理解它们的区别对性能优化很重要。
3.1 char 类型
char(L) 是定长字符串,L 指定存储长度,单位是字符而非字节。注意,utf8 编码下汉字占 3 个字节,但 char 统计的是字符个数。
CREATE TABLE test_char (name CHAR(2));
即使只存了 'a',底层也会开辟 2 个字符的空间。L 的最大值为 255。
3.2 varchar 类型
varchar(L) 是变长字符串,同样 L 表示字符长度。它不会预先分配满空间,而是用多少开多少,但总字节数不能超过 65535。
由于需要 1~3 字节记录实际长度,且受编码影响,utf8 下 varchar 的 L 最大值约为 21844。如果编码是 gbk,则最大可达 32766。
3.3 char 和 varchar 的比较
- 定长 (char):效率高,但空间浪费。适合身份证、手机号等长度固定的数据。
- 变长 (varchar):省空间,但效率略低。适合名字、地址等长度不确定的数据。
四、日期和时间类型
MySQL 常用的日期类型有三个,各自适用场景不同:
- date:格式 yyyy-mm-dd,占 3 字节。
- datetime:格式 yyyy-mm-dd HH:ii:ss,占 8 字节,范围从 1000 到 9999。
- timestamp:时间戳,格式同 datetime,占 4 字节,从 1970 年开始。
timestamp 有一个特性,当更新行时会自动更新当前时间,无需手动调用 NOW() 函数。
五、enum 和 set
这两个类型类似于 C++ 中的枚举和集合,用于限制取值范围。
- enum:单选。例如性别只能选 '男' 或 '女'。
- set:多选。例如爱好可以是 '登山'、'游泳' 的组合。
set 类型底层是按位存储的,输入数字不代表下标,而是代表比特位的位置。比如输入 1,2,3,4 对应四个比特位被置 1。
查询 set 中的数据时,不能直接用 = 号匹配所有组合,建议使用 FIND_IN_SET 函数来查找包含特定值的记录。
合理选择数据类型是构建高性能数据库的第一步,既能保证数据准确性,又能有效控制存储成本。

