MySQL中的utf8与utf8mb4区别详细对比总结

 更新时间:2026年07月28日 09:24:10   作者:翔云123456  
utf8mb4和utf8是MySQL中两种常用的字符集,它们都可以用来存储Unicode字符,但是有一些区别和联系,这篇文章主要介绍了MySQL中utf8与utf8mb4区别详细对比总结的相关资料,需要的朋友可以参考下

核心区别

utf8在MySQL中是一个"不完整"的UTF-8实现,而utf8mb4才是真正的UTF-8实现

详细对比

1.编码范围不同

字符集最大字节数支持的Unicode范围备注
utf83字节BMP平面(U+0000 ~ U+FFFF)不支持4字节字符
utf8mb44字节所有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.性能差异

方面utf8utf8mb4说明
存储空间较小较大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%';

总结建议

  1. 始终使用utf8mb4,不要使用utf8
  2. 排序规则使用utf8mb4_unicode_ci(或MySQL 8.0的utf8mb4_0900_ai_ci)
  3. 注意索引长度限制,必要时调整字段长度
  4. 确保应用程序连接字符串也使用utf8mb4
  5. 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(目前utf8utf8mb3的别名),建议明确使用utf8mb4以避免不确定性。

总结

到此这篇关于MySQL中utf8与utf8mb4区别详细对比总结的文章就介绍到这了,更多相关MySQL中utf8与utf8mb4区别内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • MySQL 8.0 Online DDL快速加列的相关总结

    MySQL 8.0 Online DDL快速加列的相关总结

    在实际的MySQL运维过程中,我们经常会遇到业务需要给某张表添加字段的情况,本文将介绍几种加字段的方法,感兴趣的朋友可以参考下
    2021-06-06
  • MySQL通过存储过程来添加和删除分区的过程(List分区)

    MySQL通过存储过程来添加和删除分区的过程(List分区)

    这篇文章主要介绍了MySQL-通过存储过程来添加和删除分区(List分区),本文通过创建存储过程来添加和删除分区,可以避免在分区存在时添加分区报错,或者分区不存在时删除分区报错的问题,需要的朋友可以参考下
    2023-09-09
  • MySQL笔记之子查询使用介绍

    MySQL笔记之子查询使用介绍

    子查询是将一个查询语句嵌套在另一个查询语句中,内层查询语句的查询结果,可以为外层查询语句提供查询条件
    2013-05-05
  • MySQL数据库Event定时执行任务详解

    MySQL数据库Event定时执行任务详解

    这篇文章主要介绍了MySQL数据库Event定时执行任务
    2017-12-12
  • 查看MySQL数据库版本的四种方法

    查看MySQL数据库版本的四种方法

    查看 MySQL 数据库的版本信息可以通过多种方法实现,包括使用命令行工具、SQL查询语句和图形化管理工具等,以下是详细的步骤和示例代码,需要的朋友可以参考下
    2025-05-05
  • 一文彻底讲清该如何处理mysql的死锁问题

    一文彻底讲清该如何处理mysql的死锁问题

    MySQL中的死锁问题是一个复杂而微妙的议题,尤其是在高并发的业务环境中,死锁可能导致服务的不稳定甚至数据的不一致,下面这篇文章主要介绍了该如何处理mysql的死锁问题的相关资料,需要的朋友可以参考下
    2024-10-10
  • 如何修改Xampp服务器上的mysql密码(图解)

    如何修改Xampp服务器上的mysql密码(图解)

    如果我们使用Xampp服务器自带数据库mysql,就必须先修改mysql的密码,下面小编给大家分享如何修改Xampp服务器上的mysql密码,需要的朋友参考下吧
    2017-04-04
  • mysql load data infile 的用法(40w数据 用了3-5秒导进mysql)

    mysql load data infile 的用法(40w数据 用了

    测试数据的时候,生成txt文件应该快点,再用这种方式导入到mysql 速度上快点,40w数据 用了3-5秒导进mysql
    2013-01-01
  • MySQL获取行号的示例代码

    MySQL获取行号的示例代码

    MySQL变量是一种用于存储和操纵数据的数据类型,通过在SQL查询中使用变量,我们可以创建一个MySQL查询,用于获取每行数据的行号,这篇文章主要介绍了MySQL 如何获取行号,需要的朋友可以参考下
    2023-08-08
  • 深入理解Mysql OnlineDDL的算法

    深入理解Mysql OnlineDDL的算法

    本文主要介绍了讲解Mysql OnlineDDL的算法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-09-09

最新评论