百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

为什么MySQL中字符集应该使用utf8mb4而不是utf8

ccwgpt 2025-02-20 14:43 48 浏览 0 评论

1. 背景

很多MySQL DBA搞不清楚MySQL中utf8字符集与utf8mb4的区别,部分人有模糊认识,认为现在应该使用utf8mb4,而不应该使用utf8字符集,但是具体是为什么,说不清楚,本文把这个问题解释清楚。

2. MySQL中的utf8字符集核utf8mb4字符集

MySQL在5.5版本之前,虽然实现了utf8字符集,但是此utf8字符集并不是完整的utf8字符集,而是只能存储UNICODE中基本多文种平面(BMP)中的字符,即65536个字符,即早些UNICODE中用2字节编码的字符。而不在这个范围内字符则不能存储。UNICODE中用2字节编码的字符用UTF-8来编码,则需要1~3个字符。utf8是一种变长编码,理论上是1~6个字节来表示4字节的UNICODE编码的字符。我们知道英文在UTF-8中是用1个字节来表示,欧洲的一些字符用2个字节来表示,而在UTF-8中绝大多数汉字是用3个字节来表示,但一些生僻汉字或表情符号是使用4个字节来表示的。

所以在MySQL中的utf8字符集只能表示1~3字节长的utf8字符,而不能表示4字节长的utf8字符。

这里解释一下基本多文种平面,BMP(Basic Multilingual Plane),或称第零平面(Plane 0),是Unicode中的一个编码区段。编码从U+0000至U+FFFF。

除了基本多文种平面,还有其它平面:

Plane

范围

名称

Plane 0

U+0000 ~ U+FFFF

基本多文种平面(Basic Multilingual Plane, BMP)

Plane 1

U+10000 ~ U+1FFFF

多文种补充平面(Supplementary Multilingual Plane, SMP)

Plane 2

U+20000 ~ U+2FFFF

表意文字补充平面(Supplementary Ideographic Plane, SIP)

Plane 3

U+30000 ~ U+3FFFF

表意文字第三平面(Tertiary Ideographic Plane, TIP)

Plane 4 ~ 13

U+40000 ~ U+4FFFF

未使用(unassigned)

Plane 14

U+E0000 ~ U+EFFFF

特别用途补充平面(Supplementary Special-purpose Plane, SSP)

Plane 15 ~ 16

U+F0000 ~ U+10FFFF

保留作为私人使用区(Private Use Area, PUA)

所以在MySQL中utf8字符集时,发现一些需要用4个字节表示的utf-8的字符,如一些生僻字无法插入到MySQL中,为了解决这个问题,MySQL在5.5.3之后增加了utf8mb4 字符编码,mb4即 most bytes 4,简单说MySQL中utf8mb4是utf8的超集并完全兼容utf8,能够用四个字节存储更多的字符。所以从这里可以知道原先 MySQL中的utf8字符集实际上是utf8mb3,即只能存最多3个字节的utf8字符。了解的utf8编码的同学可能知道utf8编码理论的长度是1~6字节,那么来一个5字节的utf8字符怎么办?从目前的情况看,全世界当前的的字符用4个字节的utf-8编码都可以容纳,还没有5个字节的utf8字符。当然未来,如果有5个字节的utf8字符出现时,MySQL的编码从utf8mb4再扩展成utf8mb5,这看着有点傻。还不如象Oracle、PostgreSQL等数据库一样,自动适应1~6个字节的utf8编码,多好?但没有办法,MySQL目前的实现就是这样。

3. 生僻字的例子:

如宋末元初官员、书法家、画家、诗人赵孟,字念“俯”,这个字就是生僻字:

我们在utf8字符集的表执行下面的SQL语句:

CREATE TABLE `test01` (  `id` int(11) DEFAULT NULL,  `t` varchar(30) COLLATE utf8_bin DEFAULT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;insert into test01 values(1, '赵孟');

在MySQL的命令行中,这个字转换成一个UNICODE的值了,并报错了:

root@localhost : db01 03:35:39> insert into test01 values(1, '赵孟\U+2B5AF');ERROR 1366 (HY000): Incorrect string value: '\xF0\xAB\x96\xAF' for column 't' at row 1Warning (Code 1300): Invalid utf8 character string: 'F0AB96'Error (Code 1366): Incorrect string value: '\xF0\xAB\x96\xAF' for column 't' at row 1

如果把表的字符集改成utf8mb4,排序规则为COLLATE=utf8mb4_unicode_ci:

CREATE TABLE `test01` (  `id` int(11) DEFAULT NULL,  `t` varchar(30) COLLATE utf8_bin DEFAULT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

这时再插入就没有问题了:

root@localhost : db01 04:07:36> insert into test01 values(1, '赵孟\U+2B5AF');Query OK, 1 row affected (0.02 sec)root@localhost : db01 04:08:00> select * from test01;+------+------------+| id   | t          |+------+------------+|    1 | 赵孟       |+------+------------+1 row in set (0.00 sec)

4. 一些注意事项

可以看:

  • mysql使用utf8mb4经验吐血总结

datax使用中的一些问题,需要在jdbc的url中添加:jdbc:mysql://ip:3306/testabc?
com.mysql.jdbc.faultInjection.serverCharsetIndex=45

具体见:
DataX:导入4字节UTF8编码(生僻字)到Mysql数据库的utf8mb4数据表

5. 总结

为了避免后续插入不了一些生僻字,在建库时就应该把默认字符集设置为utf8mb4,my.cnf的配置应该为:

[client]loose_default-character-set = utf8mb4......[mysqldump]default-character-set = utf8mb4......[mysql]default-character-set = utf8mb4......[mysqld]character-set-server=utf8mb4collation_server = utf8mb4_unicode_ci......

注意MySQL中的默认的utf8字符集实际上是utf8mb3,而不是完整的utf8,这个问题目前只在MySQL数据库中存在,PostgreSQL和Oracle是没有这个问题的,PostgreSQL数据库默认就是utf8字符集,是可以插入这些生僻字的,是没有问题的。这个问题主要是MySQL在设计之初不够严谨导致的。

相关推荐

自己动手写Android数据库框架_android开发数据库搭建

http://blog.csdn.net/feiduclear_up/article/details/50557590推荐理由关于Android数据库操作,由于每次都要自己写数据库操作,每次还得去...

谷歌开源大模型评测工具LMEval,打通谷歌、OpenAI、Anthropic

智东西编译|金碧辉编辑|程茜智东西5月28日消息,据科技媒体TheDecoder5月26日报道,当天,谷歌正式发布开源大模型评测框架LMEval,支持对GPT-4o、Claude3.7...

工信部:着力推动大模型算法、框架等基础性原创性的技术突破

工信部新闻发言人今日在发布会上表示,下一步,我们将坚持突出重点领域,大力推动制造业数字化转型,推动人工智能创新应用。主要从以下四个方面着力。一是夯实人工智能技术底座。通过科技创新重大项目,着力推动大模...

乒乓反复纠结“框架不稳定”的三个小误区

很多球友由于对框架的认知不清晰,往往会把“框架不稳定”当成一种心理负担,从而影响学球进度,其典型状态就是训练中有模有样,一旦进入实战,就像被捆住了手脚。通过训练和学习,结合“基本功打卡群”球友们交流发...

前AMD、英特尔显卡架构师Raja再战GPU,号称要全面重构堆栈

IT之家8月5日消息,知名GPU架构师拉贾科杜里(RajaKoduri)此前曾先后在AMD和英特尔的显卡部门担任要职。而在今日,由Raja创立的GPU软件与IP初创企...

三种必须掌握的嵌入式开发程序架构

前言在嵌入式软件开发,包括单片机开发中,软件架构对于开发人员是一个必须认真考虑的问题。软件架构对于系统整体的稳定性和可靠性是非常重要的,一个合适的软件架构不仅结构清晰,并且便于开发。我相...

怪不得别人3秒就知道软考案例怎么做能50+

软考高级统一合格标准必须三科都达到45分,案例分析也一直是考生头疼的一门,但是掌握到得分点,案例能不能50+还不是你们说了算吗?今天就结合架构案例考点,分享实用的备考攻略~一、吃透考点,搭建知识框架从...

UML统一建模常用图有哪些,各自的作用是什么?一篇文章彻底讲透

10万+爆款解析:9大UML图实战案例,小白也能秒懂!为什么需要UML?UML(统一建模语言)是软件开发的“蓝图”,用图形化语言描述系统结构、行为和交互,让复杂需求一目了然。它能:降低沟通成本避...

勒索软件转向云原生架构,直指备份基础设施

勒索软件组织和其他网络犯罪分子正越来越多地将目标对准基于云的备份系统,对久已确立的灾难恢复方法构成了挑战。谷歌安全研究人员在一份关于云安全威胁演变的报告中警告称,随着攻击者不断改进数据窃取、身份泄露和...

ConceptDraw DIAGRAM:释放创意,绘就高效办公新未来

在当今数字化时代,可视化工具已成为提升工作效率和激发创意的关键。ConceptDrawDIAGRAM,作为一款世界顶级的商业绘图软件,凭借其强大的功能和用户友好的界面,正逐渐成为众多专业人士的首选绘...

APP 制作界面设计教程:一步到位_app界面设计模板一套

想让APP界面设计高效落地,无需繁琐流程,掌握“框架搭建—细节填充—体验优化”三步法,即可一步到位完成专业级设计。黄金框架搭建是基础。采用“三三制布局”:将屏幕横向三等分,纵向保留三...

MCP 的工作原理:关键组件_mcp部件

以下是MCP架构的关键组件:MCP主机:像ClaudeDesktop、GitHubCopilot或旅行助手这样的AI智能体,它们希望通过MCP协议访问工具、资源等。MCP主机会...

软件架构_软件架构师工资一般多少

软件架构师自身需要是程序员,并且必须一直坚持做一线程序员。软件架构应该是能力最强的一群程序员,他们通常会在自身承接编程任务的同时,逐渐引导整个团队向一个能够最大化生产力的系统设计方向前进。软件系统的架...

不知不觉将手机字体调大!老花眼是因为“老了吗”?

现在不管是联系、交友,还是购物,都离不开手机。中老年人使用手机的时间也在逐渐加长,刷抖音、看短视频、发朋友圈……看手机的同时,人们也不得不面对“视力危机”——老花眼,习惯眯眼看、凑近看、瞪眼看,不少人...

8000通用汉字学习系列讲座(第046讲)

[表声母字]加(续)[从声汉字]伽茄泇迦枷痂袈笳嘉驾架咖贺瘸(计14字)嘉[正音]标准音读jiā。[辨形]上下结构,十四画。会意形声字,从壴从加,加也表声。注:从壴,字义与鼓乐有关;从加,字义与...

取消回复欢迎 发表评论: