SQL中数据类型char(n),varchar(n)到底占多少内存??? - 详解
此文为个人学习过程中的疑惑解答,仅供参考
char,varchar两个都是字符型的数据类型
而我今天来详细解释一下 char(n),varchar(n) 到底是什么意思,占多少内存
一、char(n)
char(n)是指的是最多许可保存n个字符,如果还有剩余则用空格补齐(看完下面的例子你会很明白的)
而char(n)具体占了多少个字节由两者决定:
1. n的大小,也就是你给它分配的可容纳字符数
2. 字符编码的选择,例:
utf8mb4中:
- 英文、数字、空格等 ASCII 字符:1 字节 / 字符;
- 中文、日文等非 ASCII 字符:3 字节 / 字符;
- Emoji 等特殊字符:4 字节 / 字符。
因此,char(3)
(允许存 3 个字符)的存储空间会根据实际存储的字符类型变化:
- 存 3 个英文(如
abc
):3 × 1 = 3 字节
; - 存 2 个中文 + 1 个空格(如
男 女
):3×2(中文) + 1×1(空格) = 7 字节
; - 存 3 个 Emoji(如
):
3 × 4 = 12 字节
。
二、varchar(n)
varcahr(n)也同样是最多行保存n个字符,只是如果还有剩余那varchar(n)不会占用剩余的空间,可是相对的,varchar会用1~2个字节去保存字符的长度(一个字节最多可指示长度为255,两个最多为65535)
varchar的实际占用空间 = 实际字符的占用空间(每种字符占用不同,能够看上面举的例子) + 1~2个用来保存字符长度的字节
三、两者分析对比
一、空间占用:varchar
更节省空间(多数场景)
char(n)
:固定占用n
个字符的空间(无论实际存储内容长短),空余部分用空格补全。- 劣势:如果实际存储的字符串长度远小于
n
,会浪费空间。例如char(20)
存储 “张三”(2 个字符),在utf8mb4
中需占用 20 个字符的空间(可能达 60 字节),但实际有效字符仅 6 字节(3×2),其余 54 字节都是补的空格。 - 特例:当存储的字符串长度固定且等于
n
时(如身份证号、手机号),char
不会浪费空间(和varchar
占用空间接近)。
- 劣势:如果实际存储的字符串长度远小于
varchar(n)
:仅占用 实际字符的字节数 + 1~2 字节的长度标记(记录字符数),不补空格。- 优势:空间利用率极高,尤其适合存储长度差异大的字符串(如姓名、地址)。例如
varchar(20)
存储 “张三”,仅占用 6(字符) + 1(长度)= 7 字节,远少于char(20)
的 60 字节。
- 优势:空间利用率极高,尤其适合存储长度差异大的字符串(如姓名、地址)。例如
二、读写性能:char
略快,但差异有限
char(n)
:- 优势:存储长度固定,数据库读取时无需计算字符串长度,可直接按固定偏移量读取,理论上速度略快。
- 适合场景:对读取性能要求极高,且字符串长度固定的场景(如存储固定格式的编号:
ABC123
、XYX789
)。
varchar(n)
:- 劣势:读取时需要先解析 “长度标记” 才能确定字符串实际长度,理论上比
char
多一步操作,性能略低。 - 但实际差异:对于短字符串(如 20 字符以内),此种性能差距几乎能够忽略;只有在超大量数据(千万级以上)且频繁读写时,才可能体现出微小差异。
- 劣势:读取时需要先解析 “长度标记” 才能确定字符串实际长度,理论上比
三、数据处理:char
需注意空格,varchar
更直观
char(n)
:- 劣势:存储时会自动在尾部补空格,查询时又会自动去掉尾部空格,可能导致逻辑混乱。例如:
char(3)
存储 “ab”,实际存的是 “ab ”(带一个空格),但查询时返回 “ab”;若用where 字段 = 'ab '
会查不到结果(因为查询时自动去空格),容易踩坑。
- 劣势:存储时会自动在尾部补空格,查询时又会自动去掉尾部空格,可能导致逻辑混乱。例如:
varchar(n)
:- 优势:严格存储输入的内容(包括空格),查询时也完全匹配,逻辑更直观。例如:
varchar(3)
存储 “ab”(带空格),查询时必须用where 字段 = 'ab '
才能匹配,符合直觉。
- 优势:严格存储输入的内容(包括空格),查询时也完全匹配,逻辑更直观。例如:
四、灵活性:varchar
更适配变化
char(n)
:- 劣势:长度固定,若后续需要存储更长的字符串(如姓名从 2 字扩展到 4 字),必须修改字段定义(
alter table
),成本较高。
- 劣势:长度固定,若后续需要存储更长的字符串(如姓名从 2 字扩展到 4 字),必须修改字段定义(
varchar(n)
:- 优势:定义时只需设置一个合理的最大长度(如
varchar(100)
),实际可存储任意长度(≤100 字符),无需频繁修改表结构,灵活性更高。
- 优势:定义时只需设置一个合理的最大长度(如
总结:如何选择?
类型 | 推荐场景 | 不推荐场景 | 核心优势 | 核心劣势 |
---|---|---|---|---|
char(n) | 字符串长度固定(如手机号、身份证号) | 字符串长度差异大(如姓名、地址) | 读写略快,无长度标记开销 | 浪费空间,空格处理麻烦 |
varchar(n) | 字符串长度不固定(如姓名、描述、备注) | 对性能极致敏感且长度固定的场景(极少) | 节省空间,灵活,逻辑直观 | 需额外存储长度标记,性能略低 |
一句话结论:除了 “长度固定且极短” 的字符串(如固定格式的编号),绝大多数场景优先用 varchar
,性价比更高。