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

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

moboyou 2025-03-11 14:33 20 浏览

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在设计之初不够严谨导致的。

相关推荐

iis部署php项目(iis发布php)

1.启动iis服务器最后点击确定就完成了2.打开iis点击进入即可3.创建网站进入添加网站。添加注意事项如图所示!启动、浏览、重启、停止网站这个如图所示。需要说明的是只要修改了配置就必须重启下网站4...

Win10安装Apache和PHP(apache安装php模块)

说明:虽然PHPStudy之类的软件给我们提供了方便的集成环境,但是其使用的是非线程安全的PHP版本(NotThreadSafe,NTS),某些功能不可以使用。所以,我们还需要自己再安装一个Apa...

两个php框架在一个网站上开发好吗

框架就是通过提供一个开发Web程序的基本架构,PHP开发框架把PHPWeb程序开发摆到了流水线上。换句话说,PHP开发框架有助于促进快速软件开发(RAD),这节约了你的时间,有助于创建更为稳定的程序,...

Ubuntu linux 上的 Nginx 和 Php 安装

教程-在UbuntuLinux上安装Nginx1.安装Nginx服务器和所需的包。apt-getupdatebrapt-getinstallnginx2.在Nginx配置文件...

网站开发初级(3) 之 PHP运行环境搭建

这篇文章主要是讲windows下php环境的搭建这里我们用的是phpstudy,作为入门学者足够了,解压安装就能用了,适当配置下基本能应付我们的开发要求下载地址:http://rj.baidu.co...

真实案例:优化用老PHP7.4的网站让其速度提高4倍

我让反应迟钝的PHP应用程序性能提升了4倍,而且我甚至没有改动任何源代码。没有重构,没有重写,只是进行了一系列精心规划的配置调整和部署优化。这篇文章将详细告诉你我是如何做到的。如果你的PHP应用程序运...

mac下快速搭建本地php开发环境(macbook开发php)

本教程主要是告诉大家,怎么快速的在mac下搭建php+mysql服务。一、安装CommandLineTools苹果系统下很多开发工具是基于CommandLineTools,所以安装它是首先。...

php手把手教你做网站(二十)vue+tp6简单案例(demo)

很多时候搭建好了环境,但是不知道怎么入手去开发。下面我们通过简单案例说明如何快速入门开发模块:例1:开发helloworld模块搭建好环境,新建项目以后,进入项目所在文件夹,依次进入src/compo...

Windows安装phpstudy(windows安装docker desktop)

说明:phpstudy是一个PHP+MySQL+Apache的集成环境,可以减少单独部署各个所需软件的麻烦,以及更加方便地切换版本。phpenv、wamp等软件的作用一样。由于环境的不同,安装过程中可...

服务器安装PHP网站的运行环境(php的服务器app)

首先要确认的是你的服务器的系统,Windows、或者linux系统。要想在Windows系统里运行php网站,可以选择iis或者Apache,如果你单独的去安装,可能会花很多时间去配置这个软件直接问题...

折腾群晖NAS:使用群晖web功能搭建个人博客「 小白玩NAS系列」

大家好,今天分享给大家如何利用群晖自带的web功能,来搭建一个属于自己的个人网站或者博客。搭建群晖web环境1、首先进入套件中心,下载webstation,群晖自带的web环境,安装会提示安装PHP...

黑客搭建钓鱼平台,手把手教你如何钓鱼?

跨站脚本攻击XSS:通过HTML注入篡改了网页,插入了恶意的脚本,从而用户浏览网页时,控制用户浏览器的一种攻击那么,我们搭建一个XSS钓鱼平台吧,注意:这个平台仅用于学习和测试,小伙伴们不要动有坏心思...

PHP 环境 搭建教程(php环境搭建apache)

PHP是一种编程语言,很多网站都用PHP语言编写,我们有时候需要测试一个网站,就需要PHP环境才能运行,又要安装Apache、又要安装MySQL……真的非常麻烦。其实我们可以使用PHP集成...

php手把手教你做网站(六)IIS创建站点注意事项

站点名称:随便填写;应用程序池:创建站点的时候会自动生成对应的,默认就好;物理路径:选择站点所在目录;类型:本地一定是http,网上可能会有https;IP地址:默认端口默认,如果是别的端口,网址访问...

分享PHP网站开发过程中的一些经验

现在的网站建设语言有几种,分别是ASP.NET,PHP,JSP这三种最为常见,这三种语言做出来的网站各有各的特点,asp属于最成熟的建站模式,jsp一般使用在大型网站系统上,对于php是目前比较流行的...