一、数据类型分类
MySQL 提供了丰富的数据类型,主要包括数值类型、字符串类型、日期和时间类型以及枚举和集合类型。
二、数值类型
2.1 整数类型
此处以 tinyint 统一进行讲解。MySQL 设计了多种整数类型,兼顾实际应用场景的需求以及数据存储空间的效率。默认情况下都是有符号整数,若是想要定义为无符号整数,则需要在类型后面添加 unsigned。整数类型除了大小不一样外,其他的使用方式基本一致。
有符号的 tinyint 类型的取值范围为 -128127,向表中插入超过数据范围的数据时会报错显示数据超过范围。无符号的 tinyint unsigned 类型的取值范围为 0255。
相较于 C/C++,当存储的数据超过了数据类型的存储范围时,编译器并不会报错,而是会发生截断或隐式类型转换。而在 MySQL 中,当我们向特定的类型中插入了非法的数据,MySQL 会直接拦截我们,不让我们进行对应的操作。如果 MySQL 也发生截断,用户就无法相信 MySQL 的数据到底是合法数据还是非法数据发生了截断。因此 MySQL 中的数据类型本身就是一种约束,约束用户保证数据的合法性。
2.2 bit 类型
bit 类型用于存储位值。MySQL 8.0 版本后,默认是以十六进制的方式来显示 bit 类型的。bit 类型没有设置位数时,则位数默认为 1,最大为 64。当用户想要操作 bit 类型的位数超过 64 时,MySQL 会对用户的操作进行拦截。
2.3 浮点数类型
2.3.1 float 类型
double 类型使用方法与 float 类型的使用方式基本一致,不同的是 double 类型存储数据的精度比 float 的精度要高。
float(M,D) 表示的范围受 M 和 D 限制。例如 float(4,2) 表示的范围是 -99.99 ~ 99.99。如果用户插入数据小数位数不足时,MySQL 会将数据的小数位数补齐。如果数据的小数位数超过了设置的位数,部分数据会被四舍五入存储,若四舍五入后超过数据的存储范围,则会被拦截。
float 类型默认为有符号类型,无符号的 float 类型同样支持四舍五入,但上限不能为正数范围的一半,且不能插入负数。当数据很大或小数点位数很多时,float 存储的数据可能会发生精度损失。
2.3.2 decimal 类型
decimal 类型的使用方式与 float 类型的方式基本一致。 decimal(4,2) 表示的范围是 -99.99 ~ 99.99,decimal(4,2) unsigned 表示的范围 0 ~ 99.99。 decimal 类型与 FLOAT 类型最大的不同就是因为存储方式不同导致的存储数据的精度不同。如果要保存的小数精度要求较高,更推荐使用 decimal 类型。
三、字符串类型
3.1 char 类型
char(size): 固定长度字符串,size 是可以存储的长度,单位为字符,最大长度值可以为 255。
在 UTF8 编码中,一个中文字符是需要占 3 个字节的,而这里插入一个中文字符却正常插入了,这是因为 size 的单位为字符而非字节。char 类型的最大长度确实为 255,当想要更长时,MySQL 就会拦截我们的操作。
3.2 varchar 类型
varchar(size): 可变长度字符串,size 表示字符长度,最大长度 65535 个字节。
关于 varchar(size),size 到底是多大,和表的编码密切相关:varchar 字节长度可以指定为 0 到 65535 之间的值,但是有 1 - 3 个字节用于记录数据大小,所以说有效字节数是 65532。
- 当我们的表的编码是 utf8mb4 时,varchar(n) 的参数 n 最大值是 65532/4=16383(因为 utf8mb4 中,一个字符占用 4 个字节)
- 当我们的表的编码是 utf8 时,varchar(n) 的参数 n 最大值是 65532/3=21844(因为 utf8 中,一个字符占用 3 个字节)
- 如果编码是 gbk,varchar(n) 的参数 n 最大是 65532/2=32766(因为 gbk 中,一个字符占用 2 字节)
3.3 char 和 varchar 比较
如何选择定长或变长字符串?
- 如果数据确定长度都一样,就使用定长(char),比如:身份证,手机号
- 如果数据长度有变化,就使用变长 (varchar),比如:名字,地址,但是你要保证最长的能存的进去。
- 定长的磁盘空间比较浪费,但是效率高。
- 变长的磁盘空间比较节省,但是效率低。
- 定长的意义是,直接开辟好对应的空间
- 变长的意义是,在不超过自定义范围的情况下,用多少,开辟多少。


