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)

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

相关推荐
cliffordl1 小时前
Web 自动化测试(Playwright)
前端·python
麦聪聊数据1 小时前
Web架构如何打通从SQL 脚本到API 服务的全链路追踪?
数据库·sql·架构
范小多1 小时前
mysql实战 C# 访问mysql(连载三)
数据库·mysql·oracle·c#
李贺梖梖1 小时前
day03 流程控制语句结构、输入
java
Q_Q5110082851 小时前
python+django/flask的在线预约导游系统
spring boot·python·django·flask·node.js
yellowCodeRabbit1 小时前
最近整理了套 Java 题库,还顺手搞了个刷题应用…
java·开发语言·资料
Austindatabases1 小时前
SQLite 开发中的数据库开发规范 --如何提升业务系统性能避免基础BUG
数据库·oracle·sqlite·bug·数据库开发
Q_Q5110082851 小时前
python+django/flask的流浪宠物领养系统
spring boot·python·django·flask·node.js·php
枫叶丹41 小时前
【Qt开发】Qt窗口(六) -> QMessageBox 消息对话框
c语言·开发语言·数据库·c++·qt·microsoft