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)

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

相关推荐
YIN_尹几秒前
CANN开源仓Catlass模板库核心能力与编程实战
java·开源·dubbo
华如锦1 分钟前
微调—— LlamaFactory工具:使用WebUI微调
java·人工智能·python·ai
武子康5 分钟前
Java-215 RocketMQ 消费模式:Push vs Pull 的本质、长轮询机制与 Offset/积压调优要
java·大数据·分布式·消息队列·rocketmq·java-rocketmq·mq
ChineHe6 分钟前
Gin框架基础篇003_响应设置详解(状态码、头信息、多格式应答体)
后端·golang·gin
侧耳倾听1117 分钟前
分布式ID之雪花算法
java·分布式
大叔_爱编程9 分钟前
基于人脸识别的互联网课堂考勤系统-springboot
java·spring boot·毕业设计·人脸识别·源码·课程设计·课堂考勤系统
云老大TG:@yunlaoda3609 分钟前
华为云国际站代理商GSL的跨境区域政策适配有哪些具体措施?
数据库·人工智能·华为云
福尔摩斯张10 分钟前
嵌入式硬件篇:常见单片机型号深度解析与技术选型指南
网络·数据库·stm32·单片机·网络协议·tcp/ip·mongodb
C嘎嘎嵌入式开发11 分钟前
语言学:自然语言处理 (NLP) 的底层逻辑
人工智能·python·自然语言处理·nlp
好记忆不如烂笔头abc11 分钟前
安装python新版本
开发语言·人工智能·python