字符串与文本类型
约 1023 字大约 3 分钟
布欧-Lewyon
2026-05-15
首页 › MySQL › 数据类型与约束(在新窗口打开) › 字符串与文本类型
MySQL 的字符串类型按存储方式分为定长字符串、变长字符串、大文本和枚举/集合四类。正确选择可显著影响存储效率和查询性能。
CHAR 与 VARCHAR
| 类型 | 特点 | 最大长度 | 存储 |
|---|---|---|---|
CHAR(M) | 定长,不足补空格 | 0~255 字符 | 固定 M 字符 |
VARCHAR(M) | 变长,按实际长度存储 | 0~65,535 字符(受行大小限制) | 实际长度 + 1~2 字节记录长度 |
区别演示
CREATE TABLE char_vs_varchar (
c CHAR(5),
v VARCHAR(5)
);
INSERT INTO char_vs_varchar VALUES ('abc', 'abc');
-- 查看实际存储长度
SELECT LENGTH(c), LENGTH(v), CHAR_LENGTH(c), CHAR_LENGTH(v) FROM char_vs_varchar;
-- CHAR(5) 存储 'abc' 时实际占用 5 字符(末尾补 2 空格,检索时自动去掉)
-- VARCHAR(5) 存储 'abc' 时实际占用 3 字符关键差异:
CHAR在检索时会自动去掉尾部空格;VARCHAR保留尾部空格。CHAR适合长度固定或接近固定的字段,如手机号、身份证号、MD5 哈希。VARCHAR适合长度不一的字段,如用户名、标题、地址。
选择建议
| 场景 | 推荐 |
|---|---|
| 手机号(11 位) | CHAR(11) |
| 中国身份证号(18 位) | CHAR(18) |
| 用户名(1~50 字符) | VARCHAR(50) |
| 邮箱地址(~254 字符) | VARCHAR(254) |
TEXT 系列(大文本)
| 类型 | 最大长度 | 说明 |
|---|---|---|
TINYTEXT | 255 字节 | 极短文本 |
TEXT | 65,535 字节(~64 KB) | 常用文章正文 |
MEDIUMTEXT | 16,777,215 字节(~16 MB) | 长文档 |
LONGTEXT | 4,294,967,295 字节(~4 GB) | 超大文本 |
CREATE TABLE article (
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(200),
body TEXT -- 正文用 TEXT 足够
);TEXT 与 VARCHAR 的差异:
- TEXT 有独立的溢出存储策略(记录前缀 + 溢出页),VARCHAR 一般是行内存储。
- TEXT 不能有默认值。
- TEXT 类型创建索引时必须指定前缀长度:
CREATE INDEX idx_body ON article(body(100))。
BLOB 系列(二进制数据)
| 类型 | 最大长度 |
|---|---|
TINYBLOB | 255 字节 |
BLOB | 64 KB |
MEDIUMBLOB | 16 MB |
LONGBLOB | 4 GB |
BLOB 存储二进制数据(图片、文件等)。但在实际项目中,更常见的做法是存储文件路径,而非直接把文件内容存入数据库,否则会导致表过大、备份缓慢。
CREATE TABLE file_record (
id INT AUTO_INCREMENT PRIMARY KEY,
filename VARCHAR(255),
filepath VARCHAR(500), -- 存储文件路径/URL
contents MEDIUMBLOB -- 直接存文件内容(不推荐)
);ENUM 与 SET
ENUM(枚举)
只能取预定义的值之一:
CREATE TABLE user (
gender ENUM('M', 'F', 'OTHER') NOT NULL
);
INSERT INTO user VALUES ('M'); -- 合法
INSERT INTO user VALUES ('X'); -- 报错:不在枚举中内部存储为整数索引(1, 2, 3...),比 VARCHAR 更省空间。
SET(集合)
可同时选择多个预定义值:
CREATE TABLE student (
hobbies SET('reading', 'sports', 'music', 'gaming')
);
INSERT INTO student VALUES ('reading,music'); -- 多值用逗号分隔
INSERT INTO student VALUES ('reading,sports,gaming');内部存储为位图(每个选项占用 1 bit)。
注意:
ENUM/SET添加新值需要通过ALTER TABLE修改定义,灵活性差。- 如果选项可能频繁变更,建议用
VARCHAR+ 代码层校验,或用字典表。
字符集对存储的影响
对于 CHAR(M) 和 VARCHAR(M),M 是字符数而非字节数。不同字符集下同一字符占用的字节数不同:
| 字符集 | 一个字符占用 | 示例 |
|---|---|---|
latin1 | 1 字节 | 英文/西欧字符 |
utf8 | 1~3 字节 | 大部分 CJK 字符 |
utf8mb4 | 1~4 字节 | 包含表情符号(emoji) |
CREATE TABLE t (
name VARCHAR(10) -- 最多存 10 个字符,无论中英文
) CHARACTER SET utf8mb4;小结
CHAR定长适合固定长度字段;VARCHAR变长适合长度不一的字段。TEXT系列存大文本,但无法设置默认值、索引需指定前缀长度。BLOB存二进制,生产环境建议存文件路径而非文件内容。ENUM单选、SET多选,内部高效但扩展性差,适用于稳定选项。- 字符数 vs 字节数:
VARCHAR(255)最大 255 字符,与字符集相关。
