【MySQL】VARCHAR(10) 和 VARCHAR(100) 的区别
目录
- VARCHAR 介绍
- VARCHAR(10)和VARCHAR(100)的区别
- 主要区别
- 最大字符数和字段值限制
- 存储和索引性能
- 总结知识点
VARCHAR 介绍
VARCHAR()
是 SQL 中用于表示变长字符串类型的一种数据类型,全称是 Variable Character。
基本语法:
column_name VARCHAR(n)
其中 n
是最大字符数(不是字节数),指定该列最多可以存储多少个字符。
示例:
CREATE TABLE users (username VARCHAR(50),email VARCHAR(100)
);
这表示:
username
字段最多存储 50 个字符;email
字段最多存储 100 个字符。
注意事项:
VARCHAR(n)
中的n
是字符数,而不是字节数。但在一些数据库中(如 MySQL 的 UTF-8 编码),一个字符可能占多个字节。VARCHAR
是变长的,存储时只占用实际字符长度 + 1 或 2 个字节的长度信息(取决于n
的大小)。- 如果超出定义长度的字符插入,有些数据库会自动截断(如 MySQL),有些会报错(如 PostgreSQL)。
CHAR vs VARCHAR:
类型 | 特点 | 适用场景 |
---|---|---|
CHAR(n) | 定长,固定占用 n 个字符空间 | 固定长度如身份证号、邮编等 |
VARCHAR(n) | 变长,占用实际长度空间 | 长度不确定的字段,如用户名、评论等 |
VARCHAR(10)和VARCHAR(100)的区别
VARCHAR(10)
和 VARCHAR(100)
的主要区别在于:允许存储的最大字符数量不同,从而影响存储空间、性能、数据约束等方面。
主要区别
比较项 | VARCHAR(10) | VARCHAR(100) | 说明 |
---|---|---|---|
最大字符数 | 10 个字符 | 100 个字符 | 限制每条数据的最大长度 |
存储空间(MySQL 举例) | 最多占 10 + 1 字节 | 最多占 100 + 2 字节 | 每条记录长度 +1 或 +2 字节用于长度信息 |
字段值限制 | 更严格 | 更宽松 | VARCHAR(10) 超出字符将被截断或报错 |
索引性能 | 更快(更短) | 稍慢(更长) | 因为字段短,索引效率可能更高 |
内存占用(In-Memory) | 更少 | 更多 | 对于大量数据,差别显著 |
最大字符数和字段值限制
举个例子:
CREATE TABLE test1 (name VARCHAR(10)
);CREATE TABLE test2 (name VARCHAR(100)
);INSERT INTO test1 VALUES ('Jonathan'); -- OK(8个字符)
INSERT INTO test1 VALUES ('Christopher'); -- 超出10个字符,报错或被截断INSERT INTO test2 VALUES ('Jonathan'); -- OK
INSERT INTO test2 VALUES ('Christopher'); -- OK(13个字符)
使用建议
- 用最小合适长度即可,不要随便用 VARCHAR(255)(很多人误以为是“无限长”)。
- 如果字段永远不会超过 20 字符,比如手机号、验证码等,用
VARCHAR(20)
。 - 如果是用户输入(如评论内容、文章标题等),可以考虑
VARCHAR(100)
或更大。
特别提示(MySQL 下)
VARCHAR(n)
的n
并不影响性能太大,但定义得太大可能会导致:- 内存浪费(InnoDB 的 row format 不一样)
- 表设计不合理
- 某些存储引擎下影响行的最大长度(例如每行不能超过 65535 字节)
存储和索引性能
在大多数数据库中(如 MySQL 的 InnoDB 引擎):
存储结构 = 实际字符串长度 + 长度标记(1字节或2字节)
实际字符串长度 | 长度标记 | 说明 |
---|---|---|
0 ~ 255 字节 | 1 字节 | 用于记录字符串长度 |
256 ~ 65535 字节 | 2 字节 | 超过255时,用2字节记录长度 |
注意:这个长度单位是“字节”,而不是“字符”。如果使用多字节字符(如 UTF-8 汉字 3 字节),就要特别注意。
示例:插入 "test"
到 VARCHAR(10)
和 VARCHAR(100)
"test"
是 4 个字符(ASCII),占 4 字节。- 插入这两个字段时,实际存储如下:
字段类型 | 实际内容长度 | 长度标记 | 总占用 |
---|---|---|---|
VARCHAR(10) | 4 字节 | 1 字节 | 5 字节 |
VARCHAR(100) | 4 字节 | 1 字节 | 5 字节 |
所以,两者在这条记录上占用空间相同。
虽然在空间占用上相同,但是在索引性能方面却有很大的差异,这是由于 VARCHAR
的预留空间导致的。
InnoDB 索引结构(B+ Tree)
- 索引的本质是一个 B+ 树
- 每个节点是一个 页(Page),大小是固定的:默认 16KB
- 每个页能放多少项?取决于字段的长度
页结构示意图
16KB 页空间
├── 页头部信息(固定大小)
├── 多个索引项(字段值 + 主键 + 元数据)
└── 页尾部信息(固定大小)
为什么定义大的 VARCHAR(n)
会浪费页空间?
因为数据库预估每个索引项最长是多少字节,如果你定义 VARCHAR(1000)
:
- 它要为最坏情况预留 1000 字节(甚至 4000 字节)
- 那 16KB 的页就只能塞 3~4 项 → 页使用效率极低
而 VARCHAR(10)
即使全是 Emoji(最大 40 字节),也能塞几百项,索引扁平、缓存友好、性能高
也就是说虽然这两个字段对于一条“短字符串”记录占用一样,但:
- VARCHAR(10) 会让数据库引擎更容易估算行宽,有利于页空间优化。
- 表中若大量字段都是
VARCHAR(100)
,哪怕只存"test"
,引擎在预估每行最大可能长度时会认为这一列是 100 字节,从而:- 导致 页中能放的记录减少;
- 查询缓存、排序、临时表占用内存更多;
- 行格式管理更加保守。
所以:
字段定义越紧凑,数据库内部的页、缓冲、排序、索引等机制就越高效。
总结知识点
知识点 | 说明 |
---|---|
VARCHAR(n) 并不预分配 n 个字符 | 是变长类型,按实际存储内容+长度标记 |
长度标记字节数 | ≤255 字节时占 1 字节,>255 时占 2 字节 |
实际空间使用 | 实际内容字节 + 1或2 字节 |
VARCHAR(10) vs VARCHAR(100) | 存“test”时占用一样,但字段更大会影响性能预估与页管理 |
多字节字符情况 | 比如 UTF-8 的汉字一个可能占 3 字节,要注意总字节限制 |
数据库页存储优化 | 使用合适大小的 VARCHAR(n) 可以减少页浪费、提高性能 |