核心区别
utf8在mysql中是一个"不完整"的utf-8实现,而utf8mb4才是真正的utf-8实现。
详细对比
1.编码范围不同
| 字符集 | 最大字节数 | 支持的unicode范围 | 备注 |
|---|---|---|---|
| utf8 | 3字节 | bmp平面(u+0000 ~ u+ffff) | 不支持4字节字符 |
| utf8mb4 | 4字节 | 所有unicode字符(包括supplementary planes) | 完整utf-8支持 |
2.历史背景
- utf8 (utf8mb3): mysql早期实现的"阉版"utf-8
- 2003年引入,当时认为3字节足够表示所有字符
- 实际是utf-8的一个子集,后来更名为
utf8mb3
- utf8mb4: mysql 5.5.3引入
- 完整的utf-8实现
- “mb4” = “multi-byte 4”
3.实际影响最明显的场景
-- 这些字符在utf8下会出错,在utf8mb4下正常
-- 表情符号(emoji)
insert into users (name) values ('小明😊开心'); -- 需要utf8mb4
-- 部分生僻汉字
insert into text (content) values ('𠀀𪚥𪚨'); -- 需要utf8mb4
-- 某些数学符号、音乐符号等
insert into symbols (symbol) values ('𝄞𝄢'); -- 需要utf8mb4
4.存储空间差异
-- 创建表对比
create table test_utf8 (
id int,
text varchar(100) character set utf8 -- 最大300字节
);
create table test_utf8mb4 (
id int,
text varchar(100) character set utf8mb4 -- 最大400字节
);
-- 注意:varchar(100)对于utf8最多存储100个字符(但可能占用最多300字节)
-- 对于utf8mb4最多存储100个字符(但可能占用最多400字节)
5.性能差异
| 方面 | utf8 | utf8mb4 | 说明 |
|---|---|---|---|
| 存储空间 | 较小 | 较大 | utf8mb4可能多用约33%空间 |
| 索引长度 | 较短 | 较长 | 索引长度限制以字节为单位 |
| 排序性能 | 稍快 | 稍慢 | 差异通常不明显 |
关键限制
索引长度限制
-- utf8: 最大索引长度 767字节 -- utf8mb4: 最大索引长度 3072字节(mysql 5.7+) -- 但在早期版本中,innodb对utf8mb4的索引限制: -- utf8: varchar(255) 可以建索引 (255×3=765 < 767) -- utf8mb4: varchar(255) 不能建索引 (255×4=1020 > 767) -- 需要改为 varchar(191) (191×4=764 < 767) -- 解决办法:修改innodb_large_prefix设置 set global innodb_large_prefix = on; set global innodb_file_format = barracuda;
实际使用建议
1.新项目一律使用utf8mb4
-- 数据库级别
create database mydb character set utf8mb4 collate utf8mb4_unicode_ci;
-- 表级别
create table mytable (
id int primary key,
content text
) character set utf8mb4 collate utf8mb4_unicode_ci;
-- 列级别
alter table mytable modify content varchar(255)
character set utf8mb4 collate utf8mb4_unicode_ci;
2.现有系统迁移步骤
-- 1. 备份数据 -- 2. 修改数据库默认字符集 alter database database_name character set utf8mb4 collate utf8mb4_unicode_ci; -- 3. 修改表字符集 alter table table_name convert to character set utf8mb4 collate utf8mb4_unicode_ci; -- 4. 修改连接配置 -- 在my.cnf中: [client] default-character-set = utf8mb4 [mysql] default-character-set = utf8mb4 [mysqld] character-set-server = utf8mb4 collation-server = utf8mb4_unicode_ci -- 5. 验证修改 show variables like 'character_set%'; show variables like 'collation%';
3.连接配置
# 命令行连接
mysql -u root -p --default-character-set=utf8mb4
# 应用程序连接示例
# python (pymysql)
conn = pymysql.connect(charset='utf8mb4')
# php (pdo)
$pdo = new pdo('mysql:host=localhost;dbname=test;charset=utf8mb4', $user, $pass);
# java (jdbc)
jdbc:mysql://localhost:3306/db?characterencoding=utf8mb4
4.排序规则选择
-- 常用排序规则 utf8mb4_unicode_ci -- 基于unicode标准排序,支持多语言(推荐) utf8mb4_general_ci -- 旧的排序规则,性能稍好但准确性较差 utf8mb4_bin -- 二进制排序,区分大小写和重音 utf8mb4_0900_ai_ci -- mysql 8.0默认,基于unicode 9.0标准 -- 查看所有utf8mb4排序规则 show collation like 'utf8mb4%';
兼容性考虑
向下兼容性
- utf8mb4完全兼容utf8(utf8mb3)存储的数据
- 反向不兼容:utf8mb4的数据可能无法在utf8中正常显示
客户端兼容性
- 所有现代客户端都支持utf8mb4
- 确保客户端连接时也使用utf8mb4字符集
验证当前设置
-- 查看数据库、表、列的字符集
select
table_schema,
table_name,
column_name,
character_set_name,
collation_name
from information_schema.columns
where table_schema = 'your_database'
and character_set_name is not null;
-- 查看当前连接的字符集
show variables where variable_name like 'character_set_%' or variable_name like 'collation%';
总结建议
- 始终使用utf8mb4,不要使用utf8
- 排序规则使用utf8mb4_unicode_ci(或mysql 8.0的utf8mb4_0900_ai_ci)
- 注意索引长度限制,必要时调整字段长度
- 确保应用程序连接字符串也使用utf8mb4
- mysql 8.0已将utf8mb4作为默认字符集
-- mysql 8.0默认设置 mysql> select @@character_set_database, @@collation_database; +--------------------------+------------------------+ | @@character_set_database | @@collation_database | +--------------------------+------------------------+ | utf8mb4 | utf8mb4_0900_ai_ci | +--------------------------+------------------------+
重要提示:mysql未来版本中,utf8可能会被重新定义为真正的utf-8(目前utf8是utf8mb3的别名),建议明确使用utf8mb4以避免不确定性。
总结
到此这篇关于mysql中utf8与utf8mb4区别详细对比总结的文章就介绍到这了,更多相关mysql中utf8与utf8mb4区别内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论