本文由 ChatMoney团队出品

之前,在将emoji表情存入MySQL时,我遇到了一个棘手的问题——数据无法导入。经过一番摸索,我将数据库编码从utf8更改为utf8mb4,问题得以解决。当时并未深究其背后的原因。

时光荏苒,一年后,我偶然读到一篇文章,提到emoji字符占用4个字节,通常需要使用utf-8编码接收,否则可能会出现错误。这让我回想起去年更改MySQL编码的经历,心中不禁产生疑问:MySQL的utf8编码难道不是真正的UTF-8编码吗?

带着这个疑问,我查阅了大量资料,发现这竟然是MySQL的一个历史遗留问题。没想到,如此强大的MySQL也有这段鲜为人知的往事。

一、回顾报错经历

当我尝试将包含emoji的文本直接写入SQL执行insert语句时,出现了以下错误:

INSERT INTO `csjdemo`.`student` (`ID`, `NAME`, `SEX`, `AGE`, `CLASS`, `GRADE`, `HOBBY`)
VALUES ('20', '陈哈哈', '男', '20', '181班', '9年级', '看片儿');
[Err] 1366 - Incorrect string value: '\xF0\x9F\x98\x93' for column 'NAME' at row 1

在将数据库编码、系统编码以及表字段的编码格式更改为utf8mb4后,问题得到了解决:

INSERT INTO `student` (`ID`, `NAME`, `SEX`, `AGE`, `CLASS`, `GRADE`, `HOBBY`)
VALUES (null, '陈哈哈', '男', '20', '181班', '9年级', '看片儿');

二、揭秘MySQL中utf8的趣事

原来,MySQL的“utf8”并非真正的UTF-8。在MySQL中,“utf8”编码每个字符最多支持三个字节,而真正的UTF-8每个字符最多支持四个字节。

在utf8编码中,中文占用3个字节,数字、英文、符号占用1个字节。而emoji符号和部分复杂文字、繁体字则占用4个字节,导致写入失败。因此,应将编码更改为utf8mb4。

令人惊讶的是,MySQL并未修复这个bug,而是在2010年发布了一个名为“utf8mb4”的字符集,巧妙地绕过了这个问题。尽管如此,他们并未广泛宣传这个新字符集,或许是因为这个bug让他们感到尴尬。因此,网络上仍有许多建议开发者使用“utf8”的误导性信息。

  1. utf8mb4:真正的UTF-8

MySQL的“utf8mb4”才是真正的“UTF-8”。MySQL的“utf8”实际上是一种“专属编码”,它能编码的Unicode字符非常有限。

在此提醒:所有使用“utf8”的MySQL和MariaDB用户都应改用“utf8mb4”,永远不要再使用“utf8”。

那么,什么是编码?什么是UTF-8?

计算机使用0和1存储文本,例如字符“C”被存为“01000011”。计算机在显示字符时需要经过两个步骤:将0和1转换为数字,再在Unicode字符集中查找对应的字符。

几乎所有的网络应用都使用Unicode字符集,因为它包含了上百万个字符。UTF-8编码可以节省空间,字符“C”只需8位,而“”这样的字符则需要32位。

  1. utf8的简史

为何MySQL开发者会让“utf8”失效?或许可以从MySQL版本提交日志中寻找答案。

MySQL从4.1版本开始支持UTF-8,即2003年。当时使用的UTF-8标准(RFC 2279)最多支持每个字符6个字节。然而,2002年3月28日,MySQL开发者在一个预览版中使用了这个标准。同年9月,他们对MySQL源代码进行了调整,使得“UTF8”最多只支持3个字节的序列。

这个变更的原因不得而知,但在迁移到Git后,许多提交者的名字丢失了。2003年9月的邮件列表中也找不到解释这一变更的线索。

我们猜测,MySQL开发者原本想帮助用户在空间和速度上取得双赢,但最终却导致了“utf8”编码的问题。因此,没有赢家。那些希望双赢的用户在使用“utf8”的CHAR列时,实际上占用的空间更大,速度也更慢。而追求正确性的用户,在使用“utf8”编码时,却无法保存4个字节的字符。

这个不合法的字符集发布后,MySQL无法修复它,因为这需要所有用户重新构建数据库。最终,MySQL在2010年发布了“utf8mb4”来支持真正的UTF-8。

关于我们

本文由ChatMoney团队出品,ChatMoney专注于AI应用落地与变现,我们提供全套、持续更新的AI源码系统与可执行的变现方案,致力于帮助更多人利用AI来变现,欢迎进入ChatMoney获取更多AI变现方案!

MySQL的utf8编码当中的疑问的更多相关文章

  1. MySQL中UTF8编码的数据在cmd下乱码

    MySQL中UTF8编码的数据在cmd下乱,在数据库ide中看到的却是中文. 其实,原因是cmd用gbk的格式来显示数据,那么我们只需要将utf-8存储的数据用gbk的格式输出到cmd即可. 解决方法 ...

  2. mysql 配置utf8 编码,支持 emoji 方法!!!

    utf8_general_ci 已经 过时了...请以后用mysql 考虑使用 utf8mb4, utf8mb4_unicode_ci!!! 兼容性更好. mysql的utf8编码的一个字符最多3个字 ...

  3. MySQL - 设置UTF-8编码

    1. 在Windows上,安装时请选择UTF-8编码,以便正确地处理中文. 在Mac或Linux上,需要编辑MySQL的配置文件,把数据库默认的编码全部改为UTF-8.MySQL的配置文件默认存放在/ ...

  4. mysql更改utf8编码方式

    方法1: 一.查看数据库编码格式 1 mysql> show variables like 'character_set_database'; 二.查看数据表的编码格式 1 mysql> ...

  5. MySQL导入utf8编码的CSV文件

    首先,作为测试,我们在这里创建一个名为testdb的数据库,和一个名为test_table的表: create database if not exists testdb default charse ...

  6. linux mysql 修改 UTF-8编码

    版本大于5.5 [mysqld]下添加的应该为:   character-set-server=utf8   collation-server=utf8_general_ci 版本小于5.5 [cli ...

  7. mysql中utf8编码的utf8_bin,utf8_general_cs,utf8_bin的区别

    utf8_general_ci 不区分大小写,这个你在注册用户名和邮箱的时候就要使用. utf8_general_cs 区分大小写,如果用户名和邮箱用这个 就会照成不良后果 utf8_bin: com ...

  8. 关于mysql使用utf8编码在cmd窗口无法添加中文数据的问题以及解决 方法二

    如果非要用cmd窗口的话,那么可以加这句话,set names gbk:

  9. 为什么不要在MySQL中使用UTF-8编码方式

    MySQL的UTF-8编码方式 MySQL 从 4.1 版本开始支持 UTF-8,也就是 2003 年,然而目前流行的UTF-8 标准(RFC 3629)是在此之后规定的.正因此,才造就了MySQL中 ...

  10. MySQL将utf8字符集改为utf8mb4

    前言 今天在查看tomcat日志时发现了一个错误:Cause: java.sql.SQLException: Incorrect string value: '\xF0\x9F\x98\x82\xF0 ...

随机推荐

  1. vue学习一(指令2.v-bind,v-model)

    2.1.v-bind:  单向绑定(修改数据项,标签内容也改变:修改标签内容,数据项不会改变) 给html标签的属性绑定,可以用来动态修改class,简写    v-bind:style    =   ...

  2. Camel多智能体框架初探

    Camel介绍 CAMEL 是一个开源社区,致力于探索代理的扩展规律.我们相信,在大规模研究这些代理可以提供对其行为.能力和潜在风险的宝贵见解.为了促进该领域的研究,我们实现了并支持各种类型的代理.任 ...

  3. Sql 字符串截取

    注意 不同数据库内置函数名称或有差异,可参考 1.从左至右截取 ①使用left()函数可以从左至右对字符串进行截取 语法:LEFT(str,length) str是要进行截取的字符串,length是要 ...

  4. 裸金属架构之服务器安装VMWare ESXI虚拟化平台详细流程

    目录1. 裸金属架构(Vcent)2. Vcent安装流程2.1 远程控制端(个人电脑)安装VMware-viclien2.2 服务器部署安装VMWare ESXI2.3 VMware-viclien ...

  5. sql server2008出现set 选项的设置不正确:"ARITHABORT”

    ( SELECT STUFF(( SELECT '','' + CODE FROM INVNEWSAL11 WHERE (MASTERI=BILRCV.SRCERI) OR (LINKERI IN ( ...

  6. 掌握FastAPI与Pydantic的跨字段验证技巧

    title: 掌握FastAPI与Pydantic的跨字段验证技巧 date: 2025/04/01 00:32:07 updated: 2025/04/01 00:32:07 author: cmd ...

  7. Python科学计算系列11—几何绘图

    1.显函数图像绘制 例:绘制y=sinx的图像 代码如下: from sympy import * x = symbols('x') plot(sin(x), (x, -2 * pi, 2 * pi) ...

  8. ESP32+Arduino入门(四):OLED屏随机显示古诗

    前言 我觉得去做一些简单又好玩的案例是入门很好的选择. 在实践的过程中会碰到很多需求很多问题在解决这些需求这些问题的过程就是在学习的过程. 今天我来分享一个随机显示古诗的案例,如果对此感兴趣可以跟我一 ...

  9. java基础之二分查找,可变参运用

    一. public class BinarySeachTest { public static void main(String[] args) { int[] arr = new int[]{22, ...

  10. Python 3.14 t-string 要来了,它与 f-string 有何不同?

    Python 最近出了个大新闻:PEP-750 t-string 语法被正式采纳了! 这意味着 Python 将在今年 10 月发布的 3.14 版本中引入一种新的字符串前缀 t,称为模板字符串(Te ...