计算机网络/计算机科学与应用/系统/运维/开发

MySQL CHAR和VARCHAR类型 详解

### 一、基础定义与核心区别

#### 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。


人生在世,不如意事十之八九;人生的滋味,哪怕是酸甜或苦辣,也要靠自己去品。人活一口气:气质看一个人的过去,气度看一个人的未来

评论

^