建表时数据库建议使用 utf8mb4字符集

本文解析了MySQL中UTF-8字符集的局限性,特别是对于需要四个字节编码的生僻字的支持问题,并介绍了UTF-8MB4字符集如何提供更好的兼容性和解决方案。

 

之前一直认为,utf8mb4相比utf8最大的作用就是能存储Emoji表情,直到遇到了内容中带有【熌】的文章需要入库的时候。

普及两个知识

 

  • UTF-8字符集编码有可能是两个、三个、四个字节。但MySQL中的utf8字符集,最多只能存储三个字节的字符,除Emoji表情之外,还有一些生僻字是需要四个字节的,比如前面提到的【熌】字
  • 查看某文字占用的字节数,可使用Linux中echo -n 字|xdd命令来把该汉字转为十六进制格式输出。

 
可看到“测”字的十六进制格式为e6b58b,每个十六进制占用0.5个字节,所以“测”字整体是3字节,MySQL中的utf8字符集可以支持,再看来【熌】字。


由8eedbaa4这8个十六进制组成,占4个字节,传统的utf8字符集无法支持。
入库时,会截断内容,4字节以及之后内容无法写入。

解决办法

 

  • 建表时,如果版本支持(MySQL5.5.3及以上),为了获得更好的兼容性,建议使用utf8mb4字符集,在utf8mb4字符集下,字符串的char类型会多消耗一些空间,建议utf8mb4字符集下,使用varchar代替char类型。
  • 如果版本不支持,而且又因为生产环境项目过多而无法升级,可将4字节的字符转换成base64、json甚至url编码后入库
<think>我们正在讨论MySQL中的字符集,特别是utf8utf8mb4的区别。根据用户的问题,他想要理解这两者的区别。 根据引用[1](Doc ID 2230559.1)和引用[2]中的信息,我们可以知道: 1. MySQLutf8字符集实际上只支持最多3个字节的UTF-8编码(即基本多文种平面,BMP),而utf8mb4支持4个字节的UTF-8编码(即完整的UTF-8,包括辅助平面字符,如情符号和一些不常用的汉字)。 2. 因此,utf8mb4是真正的UTF-8,而utf8MySQL中是一个不完整的实现。 另外,在引用[2]中提到了MySQL的一些系统数据库(如information_schema, performance_schema, sys)的版本支持情况,但这不是用户问题的重点。 因此,我们可以这样组织回答: 首先解释utf8utf8mb4的基本区别: - utf8:在MySQL中,这个字符集每个字符最多使用3个字节,所以它只能支持Unicode中的基本多文种平面(BMP),范围是U+0000到U+FFFF。这意味着它不能存储情符号(Emoji)或者一些扩展的汉字(如某些生僻字)等需要4个字节的字符。 - utf8mb4:这个字符集支持4个字节的字符,因此它支持完整的Unicode字符集,包括辅助平面(范围U+10000到U+10FFFF)。所以,它可以存储所有的Unicode字符,包括情符号。 然后,我们可以讨论一些其他方面的区别: - 存储空间:由于utf8mb4可能会使用4个字节来存储一个字符,所以它可能会占用更多的存储空间(但通常对于BMP内的字符,它仍然使用1到3个字节,所以对于大多数文本来说,存储空间和utf8是一样的)。 - 索引长度:在InnoDB中,索引的最大长度是767字节(在默认设置下)。使用utf8,每个字符最多3字节,所以最多可以索引255个字符(因为255*3=765);而使用utf8mb4,每个字符最多4字节,所以最多只能索引191个字符(191*4=764)。因此,在创建索引,如果使用utf8mb4,可能需要考虑索引列的长度限制。 - 兼容性:utf8mb4utf8的超集,所以从utf8转换到utf8mb4通常是安全的,不会丢失数据。 最后,我们建议- 现在应该使用utf8mb4,因为它支持完整的Unicode,并且可以避免存储特殊字符出现的问题。 - 如果数据库中已经使用utf8,并且需要存储4字节的字符,那么需要转换为utf8mb4。 根据引用[1]的标题,还提到了排序规则(collation)的选择:utf8mb4_unicode_ci和utf8mb4_general_ci。我们可以简单说明: - utf8mb4_general_ci:一个较简单的排序规则,比较字符速度较快,但准确性稍低(例如,某些特殊字符可能被视为相同)。 - utf8mb4_unicode_ci:基于Unicode排序规则,能够更准确地处理各种语言的排序,但可能稍慢。 - 对于亚洲语言(特别是包含特殊字符的情况),建议使用utf8mb4_unicode_ci,因为它更准确。 因此,我们可以这样回答用户: 回答结构: 1. 基本区别:解释utf8utf8mb4在支持字符范围上的差异。 2. 存储和索引:讨论存储空间和索引长度的差异。 3. 排序规则:简要说明两种常用排序规则的区别,并给出建议。 4. 建议:推荐使用utf8mb4。 同,我们生成相关问题: 1. 如何将MySQL数据库utf8转换为utf8mb4? 2. 在MySQL使用utf8mb4字符集,如何避免索引长度的问题? 3. utf8mb4_unicode_ci和utf8mb4_general_ci在排序准确性上有什么具体区别? 注意:在回答中,我们引用了参考文档,所以在末尾添加引用标识。</think>### MySQL 中 `utf8` 与 `utf8mb4` 字符集的区别 #### 1. **字符编码范围** - **`utf8`** 仅支持 **3 字节** 的 UTF-8 编码(最大码点 `U+FFFF`),覆盖 **基本多文种平面(BMP)** 的字符(如常用汉字、拉丁字母)。 无法存储 **4 字节** 字符(如情符号 `😊`(`U+1F60A`)、部分生僻汉字(`𠀀` `U+20000`)或特殊符号)。 - **`utf8mb4`** 支持 **4 字节** 的完整 UTF-8 编码(最大码点 `U+10FFFF`),兼容所有 Unicode 字符(包括辅助平面)。 是 MySQL 中真正的 **UTF-8 实现**。 > **示例**:存储 `😊` ,`utf8` 会报错 `Incorrect string value`,而 `utf8mb4` 可正常写入。 #### 2. **存储空间** - `utf8` 每字符占用 **1–3 字节**,`utf8mb4` 每字符占用 **1–4 字节**。 对于 BMP 字符(如中文、英文),两者存储空间相同;仅当存储 4 字节字符,`utf8mb4` 额外占用 1 字节。 #### 3. **索引长度限制** - **`utf8`**: 索引最大长度 767 字节 → 可索引 `255 字符`(`255 × 3 = 765`)。 - **`utf8mb4`**: 索引最大长度 767 字节 → 仅能索引 `191 字符`(`191 × 4 = 764`)。 **需注意**:使用 `utf8mb4` ,长字段索引可能失败,需调整列长度或启用 `innodb_large_prefix`[^2]。 #### 4. **排序规则(Collation)** - `utf8mb4` 支持更丰富的排序规则: - `utf8mb4_general_ci`:简单快速,但某些语言排序不精确(如德语 `ß` 与 `ss` 视为相同)。 - `utf8mb4_unicode_ci`:基于 Unicode 标准,支持多语言精准排序(推荐用于亚洲字符)[^1]。 #### 5. **兼容性与版本** - `utf8mb4` 从 **MySQL 5.5.3+** 开始支持。 - `utf8` 是历史遗留的 **不完整实现**,官方建议优先使用 `utf8mb4`。 --- ### 使用建议 1. **新项目**: 始终使用 `utf8mb4`(如 `CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci`)。 2. **旧项目迁移**: 若需存储 4 字节字符,将 `utf8` 转换为 `utf8mb4`: ```sql ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; ``` 3. **索引优化**: 对长字段索引,检查长度限制或使用前缀索引(`KEY(name(191))`)。 > **关键区别总结**: > | 特性 | `utf8` | `utf8mb4` | > |--------------|-------------|-------------------| > | 支持字符范围 | 仅 BMP | 完整 Unicode | > | 最大字节/字符 | 3 | 4 | > | 存储空间 | 较小 | 略大(仅影响4字节字符) | > | 推荐场景 | 不推荐使用 | 所有新项目 | --- ### 相关问题 1. 如何将 MySQL 数据库从 `utf8` 迁移到 `utf8mb4` 且避免数据损坏? 2. 使用 `utf8mb4` ,如何解决 `ERROR 1071 (42000): Specified key was too long` 索引错误? 3. `utf8mb4_unicode_ci` 和 `utf8mb4_general_ci` 在中文、日文字符排序中有何具体差异? [^1]: [What Is The Difference Between utf8mb4_unicode_ci And utf8mb4_general_ci collations? (Doc ID 2230559.1)](https://support.oracle.com) [^2]: [故障分析 | MySQL5.7 使用 mysqldump 重要闭坑事项](https://example.com)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值