### 一、基础定义与核心区别
#### 1. CHAR 类型
- **定长字符串**:`CHAR(n)` 中的 `n` 表示字符数(不是字节数),取值范围 0-255。
- **存储特性**:无论实际存储的字符串长度是多少,都会占用 `n` 个字符的固定空间。如果存入的字符串长度小于 `n`,MySQL 会在右侧用**空格**补齐到 `n` 个字符;查询时会自动去掉末尾的空格。
- **示例**:定义 `CHAR(5)`,存入 `'abc'`,实际存储为 `'abc '`(后面补 2 个空格),查询时返回 `'abc'`。
#### 2. VARCHAR 类型
- **变长字符串**:`VARCHAR(n)` 中的 `n` 表示最大字符数,取值范围 0-65535(但受行总字节数限制,实际最大约 65532)。
- **存储特性**:仅占用实际字符串长度 + 1/2 个字节(用于记录长度)的空间,不会补齐空格。
- **示例**:定义 `VARCHAR(5)`,存入 `'abc'`,实际仅存储 `'abc'` + 1 个字节(记录长度),总占用 4 个字节(字符+长度标识)。
### 二、详细对比(表格更清晰)
| 特性 | CHAR(n) | VARCHAR(n) |
|---------------------|----------------------------------|---------------------------------|
| 长度特性 | 定长 | 变长 |
| 存储空间 | 固定占用 n 个字符空间 | 实际长度 + 1/2 字节(长度标识) |
| 末尾空格处理 | 存储时补空格,查询时自动去除 | 保留末尾空格(按实际存储) |
| 最大长度 | 255 个字符 | 65535 个字符(受行限制) |
| 性能 | 读写速度快(无需计算长度) | 读写稍慢(需计算/存储长度) |
| 适用场景 | 长度固定的字符串(如手机号、邮编)| 长度不固定的字符串(如姓名、描述)|
### 三、字节数补充说明(重要)
MySQL 中字符数 ≠ 字节数,取决于字符集:
- **ASCII/拉丁字符集**:1 个字符 = 1 字节;
- **UTF8(utf8mb3)**:1 个字符 = 1-3 字节;
- **UTF8mb4**:1 个字符 = 1-4 字节(支持 emoji)。
例如:
- `CHAR(10) CHARACTER SET utf8mb4`:固定占用 40 字节(10*4);
- `VARCHAR(10) CHARACTER SET utf8mb4`:存储 `'abc'` 时占用 3(字符)+1(长度标识)=4 字节。
### 四、实操示例
#### 1. 创建表并插入数据
```sql
CREATE TABLE test_string (
id INT PRIMARY KEY AUTO_INCREMENT,
char_col CHAR(5), -- 定长5字符
varchar_col VARCHAR(5) -- 变长最大5字符
);
-- 插入测试数据
INSERT INTO test_string (char_col, varchar_col)
VALUES
('abc', 'abc'), -- 长度3
('12345', '12345'), -- 长度5
('', ''), -- 空字符串
('a ', 'a '); -- 带末尾空格
```
#### 2. 查询验证
```sql
-- 查看原始数据
SELECT
char_col,
LENGTH(char_col) AS char_len, -- 字节长度
varchar_col,
LENGTH(varchar_col) AS varchar_len
FROM test_string;
```
**查询结果解析**:
| char_col | char_len | varchar_col | varchar_len |
|----------|----------|-------------|-------------|
| abc | 3 | abc | 3 |
| 12345 | 5 | 12345 | 5 |
| | 0 | | 0 |
| a | 1 | a | 3 |
- `char_col` 中 `'a '` 查询时末尾空格被自动去除,长度为 1;
- `varchar_col` 中 `'a '` 保留末尾空格,长度为 3。
### 五、使用建议
1. **优先用 CHAR 的场景**:
- 字符串长度固定(如手机号 `CHAR(11)`、邮编 `CHAR(6)`、性别 `CHAR(1)`);
- 频繁查询、对性能要求高的场景(定长存储读写更快);
- 存储很短的字符串(如状态码 `CHAR(2)`)。
2. **优先用 VARCHAR 的场景**:
- 字符串长度不固定(如姓名、地址、商品描述);
- 节省存储空间(避免定长补空格浪费空间);
- 存储长度超过 255 字符的字符串(CHAR 最大仅 255)。
3. **注意事项**:
- 不要为 VARCHAR 定义过大的 `n`(如 `VARCHAR(65535)`),会增加内存消耗;
- 存储超长文本(如文章内容),优先用 `TEXT` 类型,而非 VARCHAR;
- 若字符串可能为 NULL,CHAR 和 VARCHAR 都支持,但 CHAR(0) 不支持 NULL。
### 总结
1. **核心区别**:CHAR 是定长(补空格、查询去空格),VARCHAR 是变长(按实际长度存储、保留空格);
2. **性能与空间**:CHAR 读写快但可能浪费空间,VARCHAR 节省空间但读写稍慢;
3. **选型原则**:长度固定用 CHAR,长度不固定用 VARCHAR,超长文本用 TEXT。