MySQL的utf8编码当中的疑问
本文由 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”的误导性信息。
- 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位。
- 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编码当中的疑问的更多相关文章
- MySQL中UTF8编码的数据在cmd下乱码
MySQL中UTF8编码的数据在cmd下乱,在数据库ide中看到的却是中文. 其实,原因是cmd用gbk的格式来显示数据,那么我们只需要将utf-8存储的数据用gbk的格式输出到cmd即可. 解决方法 ...
- mysql 配置utf8 编码,支持 emoji 方法!!!
utf8_general_ci 已经 过时了...请以后用mysql 考虑使用 utf8mb4, utf8mb4_unicode_ci!!! 兼容性更好. mysql的utf8编码的一个字符最多3个字 ...
- MySQL - 设置UTF-8编码
1. 在Windows上,安装时请选择UTF-8编码,以便正确地处理中文. 在Mac或Linux上,需要编辑MySQL的配置文件,把数据库默认的编码全部改为UTF-8.MySQL的配置文件默认存放在/ ...
- mysql更改utf8编码方式
方法1: 一.查看数据库编码格式 1 mysql> show variables like 'character_set_database'; 二.查看数据表的编码格式 1 mysql> ...
- MySQL导入utf8编码的CSV文件
首先,作为测试,我们在这里创建一个名为testdb的数据库,和一个名为test_table的表: create database if not exists testdb default charse ...
- linux mysql 修改 UTF-8编码
版本大于5.5 [mysqld]下添加的应该为: character-set-server=utf8 collation-server=utf8_general_ci 版本小于5.5 [cli ...
- mysql中utf8编码的utf8_bin,utf8_general_cs,utf8_bin的区别
utf8_general_ci 不区分大小写,这个你在注册用户名和邮箱的时候就要使用. utf8_general_cs 区分大小写,如果用户名和邮箱用这个 就会照成不良后果 utf8_bin: com ...
- 关于mysql使用utf8编码在cmd窗口无法添加中文数据的问题以及解决 方法二
如果非要用cmd窗口的话,那么可以加这句话,set names gbk:
- 为什么不要在MySQL中使用UTF-8编码方式
MySQL的UTF-8编码方式 MySQL 从 4.1 版本开始支持 UTF-8,也就是 2003 年,然而目前流行的UTF-8 标准(RFC 3629)是在此之后规定的.正因此,才造就了MySQL中 ...
- MySQL将utf8字符集改为utf8mb4
前言 今天在查看tomcat日志时发现了一个错误:Cause: java.sql.SQLException: Incorrect string value: '\xF0\x9F\x98\x82\xF0 ...
随机推荐
- OSPF各类LSA
一.域内路由 路由器将接口宣告进OSPF进程后,形成的链路状态放入1类LSA中,用于描述路由器自身的直连状态. 1. 区域0为骨干区域,非0为非骨干区域. 2. 骨干区域有且只能存在一个. 3. 非骨 ...
- g2o优化库实现曲线拟合
g2o优化库实现曲线拟合 最近学习了一下g2o优化库的基本使用,尝试着自己写了一个曲线拟合的函数,也就是下面这个多项式函数: \[y = ax^3 + bx^2 + cx + d \] 我们以 \(a ...
- 在 Hugging Face Spaces 上使用 Gradio 免费运行 ComfyUI 工作流
简介 在本教程中,我将逐步指导如何将一个复杂的 ComfyUI 工作流转换为一个简单的 Gradio 应用程序,并讲解如何将其部署在 Hugging Face Spaces 的 ZeroGPU 无服务 ...
- IE 条件注释
参考文档 IE6 IE7 IE8 IE9 IE10 Css hack及IE条件注释法 IE的有条件注释判定IE版本详解(附实例代码)
- Windows IntelliJ IDEA 快捷键终极大全
自动代码 常用的有fori/sout/psvm+Tab即可生成循环.System.out.main方法等boilerplate样板代码 . 例如要输入for(User user : users)只需输 ...
- @ResponseBody 响应 json 数据
/** * 将json数据封装到bean对象中条件: * 1:json数据中的key名必须和bean对象的属性相同 * 2:添加jsonjar包的支持 * 作用:使用@ResponseBody 注解实 ...
- 🎀git统计某段时间内代码的修改量/总代码量
1.前往git本地项目路径下 2.右键打开Git Bash工具 3.输入命令: 3.1.某段时间代码修改量 git log --since=2021-01-01 --until=2021-05-18 ...
- Streamlit快速入门指南
theme: orange Streamlit是一个Python库,允许您创建交互式的数据科学和机器学习Web应用程序. Streamlit介绍 Streamlit是一个Python库,允许您创建交互 ...
- nodejs隐藏窗口启动redis服务,一个vbs文件即可
网上也有很多类似的,但基本都是用nodejs调.vbs,然后间接调.bat,经过多番尝试发现其实合并为一个文件亦可 将如下内容保存为.vbs文件,如startRedis.vbs (在nw的根目录) s ...
- K8s Pod 控制器介绍及应用示例
Kubernetes 官方文档:Pod 控制器 Pod控制器介绍 Pod是kubernetes的最小管理单元,在kubernetes中,按照pod的创建方式可以将其分为两类: 自主式pod:kuber ...