MySQL【数据类型】:CHAR 和 VARCHAR 的对比、VATCHAR(n) 和 INT(n) 里的 n 一样吗?

思维导图

一、MySQL 的数据类型

在 MySQL 中,定义字段的类型对数据库的优化是非常重要的。

MySQL 支持多种类型,大致可以分为三类:

  • 数值
  • 日期/时间
  • 字符串

(一)数值类型

示例:大整型

sql 复制代码
age int

示例:小数型

sql 复制代码
-- score(总长度, 小数点后保留的位数)
-- eg:数据范围0~100,小数点后两位 
score(5, 2)

(二)日期和时间类型

表示时间值的日期和时间类型为DATETIME、DATE、TIMESTAMP、TIME和YEAR。

每个时间类型有一个有效值范围和一个"零"值,当指定不合法的MySQL不能表示的值时使用"零"值。

(三)字符串类型

1. 定长字符串 CHAR

举例:name char(10)

如果存储字符串'张三',虽然只有2个字符,但仍会占用10个字符空间

  • 存储性能好:一律占用固定的字符空间
  • 浪费空间
  • 什么时候用?如果能确定字符的长度,比如存储性别

2. 变长字符串 VARCHAR

举例:name varchar(10)

如果存储字符串'张三',只会占用2个字符空间。

  • 存储性能不佳:varchar需要先计算字符串长度,再进行存储,所以varchar的性能不佳。
  • 节约空间
  • 什么时候用?如果不能确定字符的长度,比如存储用户名

3. CHAR 和 VARCHAR 的对比

特性 CHAR**(空间换性能)** VARCHAR**(性能换空间)**
类型 定长 变长
存储空间 固定长度 实际长度 + 1/2 字节
空间利用率 较低 较高
性能 读写更快(无需长度解析) 读写略慢(需处理长度信息)
适合场景 身份证、性别、国家代码 姓名、地址、备注、文章标题

ps:char(n) 和 varchar(n) 中括号中 n 代表字符的个数,并不代表字节个数,比如 CHAR(30) 就可以存储 30 个字符。

4. VARCHAR(n) 和 INT(n)

类型 括号里的 n 到底指什么 是否影响存储空间 是否影响可存数值/字符数 备注
INT(n) "显示宽度"(zerofill 时补零对齐) ❌ 不决定字节数,始终是 4 B ❌ 不限制数值大小 无 zerofill 时 n 完全没用;MySQL 8 已弃用显示宽度
VARCHAR(n) "字符数上限"(不是字节) ✅ 实际存多少占多少 + 1~2 B 长度前缀 ✅ 超出 n 会报错或截断 UTF-8 下每个字符可能 1~4 B,但 n 仍按字符计数
  • varcahr(n) 中的 n 代表 最多能存 n 个字符,它会影响存储空间和允许的长度。
  • int(n) 中的 n 它不是存储长度,只是代表 显示宽度, 一般情况下没有意义,比如 int(1) 和 int(20) 存储和计算其实是一样的。

二、案例

需求: 设计一张学生表,请注重数据类型,长度的合理性

  1. 编号
  2. 姓名,姓名最长不超过10个汉字
  3. 性别,因为取值只有两种可能,因此最多一个汉字
  4. 生日,取值为年月日
  5. 入学成绩,小数点后保留两位
  6. 邮件地址,最大长度不超过64
  7. 家庭联系电话,不一定是手机号码,可能会出现 - 等字
  8. 学生状态(用数字表示,正常,休学,毕业...)
sql 复制代码
create table student(
  id int,
  name varchar(10),
  gender char(1),
  birthday date,
  score double(5,2),
  email varchar(64),
  tel varchar(15),
  status tinyint
);

查询表格的结构信息:

三、相关面试题

varchar 与 char 的区别是什么?

CHAR(定长字符类型) ,是一种 固定长度 的字符串类型。占空间固定、读写快,适合固定长度字段。
VARCHAR(变长字符类型) ,是一种 可变长度 的字符串类型。空间利用率高,但读取时需要额外处理长度。

  • 比如 char(128),不管存多长的字符串,它都会占满 128 个字符的空间;
  • 而 varchar(128),只会按实际字符串长度占用空间,只要不超过 128 就行。

varchar(1000) 一定比 varchar(100) 好吗?

**等价问题:**既然varchar是变长,那是不是设置varchar(1000)一定比varchar(100)好?

不是这样的。虽然varchar是变长,在相同长度下,磁盘空间占用一样,将值设置更大一些,弹性空间也更大。但也不是完全没有代价的。

在内存加载的时候,每次都是按最大空间来分配的。显然,在排序场景,或者一些临时表聚合场景,更大空间会产生明显的不利影响。

提示:

varchar中的长度不光影响磁盘空间 ,还会影响在使用时的内存空间,并不是越长越好,这也是个常见且易踩坑的考点。

varchar 能完全代替 char 吗?

不能。varchar 的优点是更灵活。但是 char

也不是一无是处的。

  • 首先,varchar 会额外用一个字节存储长度信息,而 char 则节约了一个字节;
  • 其次,char 的存储空间都是一次性分配的,存储是固定连续的,而 varchar 的存储的长度是可变的,当 varchar
    更改前后数据长度不一致时,就不可避免的会出现碎片的问题。针对上述情况,需要进行碎片消除作业,也是额外的成本。

所以一般来说,长度固定的字段,还是用char比较合适,比如Hash,就很适合用 char。

为什么 VARCHAR 会碎片化?

VARCHAR 是可变长度类型,它的空间会随着内容的增删而变化。 当更新 VARCHAR

时,如果新内容比原来长,可能放不进原位置,InnoDB 就需要把它移动到别的页里,原位置留下空洞,久而久之就出现了碎片。

所以 VARCHAR 容易产生页分裂和空间碎片,而 CHAR 不会,因为 CHAR 是固定长度的。

varchar(11) 和 int(11) 中的 11 有什么区别?

varcahr 中的 11 代表
最多能存 11
个字符
,它会影响存储空间和允许的长度。

而 int 中的 11 它不是存储长度,只是代表
显示宽度 , 一般情况下没有意义,比如 int(1) 和 int(20)

存储和计算其实是一样的。

相关推荐
tjjucheng21 小时前
靠谱的小程序定制开发哪个好
python
num_killer21 小时前
小白的Langchain学习
java·python·学习·langchain
氦客21 小时前
Android Compose : 传统View在Compose组件中的等价物
android·compose·jetpack·对比·传统view·等价物·compose组件
WangYaolove131421 小时前
基于深度学习的中文情感分析系统(源码+文档)
python·深度学习·django·毕业设计·源码
2501_9481953421 小时前
RN for OpenHarmony英雄联盟助手App实战:主导航实现
数据库
Filotimo_1 天前
N+1查询问题
数据库·oracle
神话20091 天前
Rust 初体验与快速上手指南
android·rust
期待のcode1 天前
Java虚拟机的运行模式
java·开发语言·jvm
程序员老徐1 天前
Tomcat源码分析三(Tomcat请求源码分析)
java·tomcat
a程序小傲1 天前
京东Java面试被问:动态规划的状态压缩和优化技巧
java·开发语言·mysql·算法·adb·postgresql·深度优先