当前位置: 首页 > news >正文

求求你,别在 MySQL 中使用 UTF-8了!

一、 为什么说"别在 MySQL 中使用 UTF-8"?

这个说法听起来有点耸人听闻,但它精准地指出了 MySQL 长久以来存在的一个大问题:MySQL 中的 "utf8" 实际上不是真正的 UTF-8 编码

1.1 "utf8" vs. "utf8mb4":一字之差,天壤之别
  • MySQL 的 "utf8" (别名 utf8mb3):这是一种"专属编码",它只支持每个字符最多3 个字节的 UTF-8 字符 。这意味着,它只能编码 Unicode 中的基本多文种平面(BMP)的字符。

  • 真正的 UTF-8 编码:标准的 UTF-8 编码是变长的,每个字符使用 1 到4 个字节进行编码。

  • MySQL 的 "utf8mb4":这才是真正的 UTF-8 编码,支持每个字符最多4 个字节,能够编码所有 Unicode 字符 。

1.2 问题的根源:一个无法挽回的历史错误

为什么 MySQL 会犯这样的错误?这要从历史说起。在 MySQL 最早开发时,Unicode 还处于早期阶段,当时的确没有需要 4 字节编码的字符。为了追求存储空间和性能的极致优化,MySQL 的设计者们决定创造一种自己的"utf8",硬性限制为 3 字节 。

然而,随着 Unicode 的发展,越来越多的生僻字、特殊符号以及如今无处不在的Emoji 表情符号(如😂👍🏻)被纳入标准,它们都需要 4 个字节进行存储。当用户尝试将这些字符插入到"utf8"编码的列中时,MySQL 就会报错,例如:
Incorrect string value: '\xF0\x9F\x98\x82' for column 'name' at row 1

到了 2010 年,MySQL 终于意识到这个问题的严重性,但已经无法回头了。如果直接修改"utf8"的定义,将会导致所有现有用户的数据损坏或需要重构数据库。因此,他们选择了一个折中方案:新推出一个名为 "utf8mb4" 的字符集来真正支持完整的 UTF-8 编码,并让它作为真正的 UTF-8 标准

二、 我们应该怎么做?全面拥抱 utf8mb4

理解了问题的根源,解决方案就非常清晰了:所有还在使用 "utf8" 的用户,都应该立即改用 "utf8mb4"

2.1 基础设置:从源头抓起

最好的方式是在一开始创建数据库和表时就指定正确的字符集。

  • 创建数据库时指定

    sql

    CREATE DATABASE my_database CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
  • 创建表时指定

    sql

    CREATE TABLE my_table ( id INT PRIMARY KEY AUTO_INCREMENT, content TEXT ) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
2.2 如何选择正确的排序规则 (COLLATION)

字符集之外,排序规则也至关重要。针对utf8mb4,常见的排序规则有以下几种:

  • utf8mb4_general_ci

    • 特点:比较和排序速度快 。

    • 缺点:对某些语言的排序规则支持不够精确,比如德语、法语中的一些特殊字符排序可能不符合当地习惯。

  • utf8mb4_unicode_ci

    • 特点:基于标准的 Unicode 排序规则算法,支持多语言,排序结果更准确 。

    • 缺点:相比general_ci,性能会稍有损耗,但在绝大多数场景下可以忽略不计。

  • utf8mb4_0900_ai_ci(MySQL 8.0+ 默认)

    • 特点:基于 Unicode 9.0 标准,是unicode_ci的升级版,提供了更准确的排序,并且ai表示不区分重音(Accent Insensitive),ci表示不区分大小写(Case Insensitive)。

    • 建议:如果你的 MySQL 版本是 8.0 或更高,强烈推荐使用这个默认规则 。

最佳实践建议:如果不确定选哪个,直接使用 MySQL 8.0 默认的utf8mb4_0900_ai_ci。如果你的版本较低(5.5.3 以上),推荐使用utf8mb4_unicode_ci,在准确性和性能上取得了很好的平衡 。

2.3 修改现有数据库、表和列

如果你的项目已经存在,需要将旧的utf8数据迁移到utf8mb4

  • 修改数据库的默认字符集

    sql

    ALTER DATABASE database_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;

    注意:这只会修改新表的默认字符集,不会改变现有表和列。

  • 修改表和列的字符集(推荐方法)
    使用CONVERT TO CHARACTER SET可以一次性转换表和所有列的字符集 。

    sql

    ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

    ⚠️ 警告:对于大表,这个操作可能会非常耗时,并会对数据库造成较大压力,建议在业务低峰期进行,并提前做好备份 。

2.4 配置文件和服务端的统一

仅仅修改数据库还不够,需要确保从客户端到服务端的整个链路字符集都是统一的 。

编辑 MySQL 的配置文件(Linux 通常是/etc/my.cnf/etc/mysql/my.cnf,Windows 是my.ini),在对应区域添加或修改如下配置 :

ini

[client] default-character-set = utf8mb4 [mysql] default-character-set = utf8mb4 [mysqld] character-set-client-handshake = FALSE character-set-server = utf8mb4 collation-server = utf8mb4_unicode_ci # MySQL 8.0 可以使用默认的 utf8mb4_0900_ai_ci # collation-server = utf8mb4_0900_ai_ci # 可选,但推荐:防止客户端连接时覆盖服务端设置 skip-character-set-client-handshake

修改完成后,重启 MySQL 服务使配置生效 。

2.5 应用层连接的设置

最后,应用程序在连接数据库时,也需要指定使用utf8mb4字符集 。

  • 使用 SQL 命令(连接后执行)

    sql

    SET NAMES 'utf8mb4';
  • 在 JDBC 连接 URL 中指定(Java 应用)
    确保 URL 中设置characterEncoding=utf8mb4。并且可以移除旧的characterEncoding=utf-8设置。

    text

    jdbc:mysql://localhost:3306/my_database?useUnicode=true&characterEncoding=utf8mb4&serverTimezone=UTC
  • 在 Python (MySQLdb/ PyMySQL)中指定
    在建立连接时,传入charset="utf8mb4"参数 。

三、 总结与展望

MySQL 的 "utf8" 字符集是一个历史遗留的"坑",它并不是真正的 UTF-8。为了存储 Emoji 表情和生僻汉字,确保数据的完整性和未来的兼容性,必须使用 "utf8mb4" 字符集

http://www.jsqmd.com/news/387396/

相关文章:

  • 吐血推荐!更贴合专科生的AI论文网站,千笔·专业学术智能体 VS 灵感ai
  • 面试官:什么是 NIO?NIO 的原理是什么机制?
  • 赶deadline必备AI论文网站 千笔AI VS 学术猹 研究生专属神器
  • 高级玩家必备:深度剖析 MySQL 事务隔离!
  • 题解:洛谷 P1980 [NOIP 2013 普及组] 计数问题
  • 题解:洛谷 P1009 [NOIP 1998 普及组] 阶乘之和
  • 少走弯路:专科生专属降AIGC工具 千笔·专业降AI率智能体 VS 万方智搜AI
  • 基于FPGA的视频缩放算法:4K2K输入与输出,缩放参数可控
  • 闭眼入!9个AI论文工具测评:本科生毕业论文写作全攻略
  • 好用还专业! 降AIGC平台 千笔·降AI率助手 VS 学术猹 MBA首选
  • 交稿前一晚!9个AI论文工具测评:研究生毕业论文+学术写作全攻略
  • 摆脱论文困扰! AI论文网站 千笔写作工具 VS 学术猹,自考首选!
  • 题解:洛谷 P5721 【深基4.例6】数字直角三角形
  • 光伏mppt电导增量法mppt模型,可以实现最大功率电的追踪,模型可以正常运行,可拓展性强
  • 最近在搞综合能源系统规划,发现双层优化建模挺有意思。今天咱们就来聊聊怎么用双层模型搞定微电网的多电源容量配置,手把手带你撸一遍代码实现
  • 快递小车自动避人配送,识别行人优先避让,小区配送,输出平稳送达。
  • SpringBoot 的启动引导类真的是 XXApplication 吗?
  • RISC(Reduced Instruction Set Computing,精简指令集计算机)和CISC(Complex Instruction Set Computing,复杂指令集计算机)
  • 面试官:给我说一下 Spring MVC 拦截器的原理?
  • 流量思维向长效思维转型:开源链动2+1模式AI智能名片小程序赋能私域电商品牌建设
  • 技术赋能直播运营:开源AI智能名片商城小程序助力个人IP构建与高效运营
  • 分布式系统的接口幂等性设计详解
  • 第4章 变量:数据的容器-小结
  • 第4章 变量:数据的容器-4.1 变量的概念:为什么需要变量?
  • 2026信奥培训怎么选?十大品牌综合实力榜出炉!选对品牌事半功倍 - 匠言榜单
  • 2026年热门止痒去屑洗发水排行,告别头屑烦恼,去屑洗发水/去油去屑洗发水/止痒去屑洗发水,止痒去屑洗发水品牌怎么选择 - 品牌推荐师
  • 学霸同款! 降AIGC网站 千笔·专业降AI率智能体 VS 云笔AI
  • COMSOL相控阵超声仿真:Phased Array Focus与压力声学模块
  • Spark大数据处理:技术、应用与性能优化【2.3】
  • AI技术驱动下的SEO关键词优化新策略解析与实践