Loading... ## 前言 ## - 今天在写文章的时候,使用<span class="external-link"><a class="no-external-link" href="https://emojipedia.org/" target="_blank"><i data-feather="external-link"></i>这里</a></span>面的emoji表情无法储存,报错:Database Query Error。 <div class="preview"> <div class="post-inser post box-shadow-wrap-normal"> <a href="" target="_blank" class="post_inser_a no-external-link no-underline-link"> <div class="inner-content" style="margin-left: 10px;"> <p class="inser-title">文章不存在,或文章是加密、私密文章</p> <div class="inster-summary text-muted"> </div> </div> </a> <!-- .inner-content #####--> </div> <!-- .post-inser ####--> </div> - 经查询emoji占用4个字节,而我博客使用的utf8的编码,mysql中utf8最多只支持3个字节。 ## 解决方案 ## 1. mysql配置文件添加如下参数 ```properties default-character-set = utf8mb4 default-character-set = utf8mb4 character-set-client-handshake = FALSE character-set-server = utf8mb4 collation-server = utf8mb4_unicode_ci init_connect='SET NAMES utf8mb4' ``` 2. 修改数据库 charset 为 utf8mb4 ```mysql ALTER DATABASE database_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci; ``` 3. 执行以下编码(下面的sql语句表名是我博客用的表名,这里把所有的表都修改了) ```mysql alter table typecho_comments convert to character set utf8mb4 collate utf8mb4_general_ci; alter table typecho_contents convert to character set utf8mb4 collate utf8mb4_general_ci; alter table typecho_fields convert to character set utf8mb4 collate utf8mb4_general_ci; alter table typecho_metas convert to character set utf8mb4 collate utf8mb4_general_ci; alter table typecho_options convert to character set utf8mb4 collate utf8mb4_general_ci; alter table typecho_relationships convert to character set utf8mb4 collate utf8mb4_general_ci; alter table typecho_users convert to character set utf8mb4 collate utf8mb4_general_ci; ``` 4. 博客专有(修改 Typecho 配置文件 config.inc.php 中数据库定义参数中的 charset 为 utf8mb4) ```php 'charset' => 'utf8mb4', ``` ## 延伸知识 ## 1. 最初的 UTF-8 格式使用一至六个字节,最大能编码 31 位字符。最新的 UTF-8 规范只使用一到四个字节,最大能编码21位,正好能够表示所有的 17个 Unicode 平面。 2. utf8 是 Mysql 中的一种字符集,只支持最长三个字节的 UTF-8字符,也就是 Unicode 中的基本多文本平面。 3. Mysql 中的 utf8 为什么只支持持最长三个字节的 UTF-8字符呢?可能是因为 Mysql 刚开始开发那会,Unicode 还没有辅助平面这一说呢。那时候,Unicode 委员会还做着 “65535 个字符足够全世界用了”的美梦。Mysql 中的字符串长度算的是字符数而非字节数,对于 CHAR 数据类型来说,需要为字符串保留足够的长。当使用 utf8 字符集时,需要保留的长度就是 utf8 最长字符长度乘以字符串长度,所以这里理所当然的限制了 utf8 最大长度为 3,比如 CHAR(100) Mysql 会保留 300字节长度。至于后续的版本为什么不对 4 字节长度的 UTF-8 字符提供支持,我想一个是为了向后兼容性的考虑,还有就是基本多文种平面之外的字符确实很少用到。 4. 要在 Mysql 中保存 4 字节长度的 UTF-8 字符,需要使用 utf8mb4 字符集,但只有 5.5.3 版本以后的才支持(查看版本: select version();)。我觉得,为了获取更好的兼容性,应该总是使用 utf8mb4 而非 utf8. 对于 CHAR 类型数据,utf8mb4 会多消耗一些空间,根据 Mysql 官方建议,使用 VARCHAR 替代 CHAR。 ## 建议 ## <div class="tip inlineBlock info"> 建议普通表使用utf8, 如果这个表需要支持emoji就使用utf8mb4 </div> ## 摘要 ## <button class=" btn m-b-xs btn-success " onclick="window.open('https://www.lanka.cn/Typecho-6_3759.html','_blank')">解决方案</button> 最后修改:2020 年 12 月 02 日 © 来自互联网 打赏 赞赏作者 支付宝微信 赞 社会很单纯~复杂滴是人呐~谁能在乎我呀