mysql中的utf8与utf8mb4

article/2025/8/31 2:40:13

一、如何设置utf8mb4

mysql中针对字符串类型,在设置charset的时候可以精确到字段。

如果只将某个字段设置utf8mb4,那么其他字段不会受影响。

如果针对表来设置,那么已经存在的字段依然是utf8,并且会多出utf8的标记,之后所创建的字段才会是utf8mb4

如果针对库来设置,那么已经存在的表依然是utf8,之后所创建的表才会是utf8mb4

除此之外呢,我们在连接数据库的时候,也要指明charset=utf8mb4,否则的话,此连接无法向utf8mb4的字段写入数据,并且读取的时候是乱码。

在使用 navicat 的时候,发现没有地方设置连接的字符编码,他会自动扫面你的数据库,表,字段的编码,来自动设置一个合适的编码,当然,这也跟 navicat 版本有关,高版本才行,我的低版本就不行,如果你发现你的 navicat 无法显示表情,只能看到问好,那么可以通过show variables like '%char%'查看一下。

我还遇到一个情况,我的 navicat 没法自动设置 utf8mb4,因此,在 utf8 的情况下,我将线上的表情同步到了我本地,这使得我在后面即使设置了 utf8mb4 的情况下也看不到表情,这是因为我在 utf8 的时候同步过来的数据被破坏了,字符集不兼容,所以需要先设置好字符编码再拉取一次数据。

二、问题

1、为什么存储的时候要区分utf8和utf8mb4

按理说,不管我存进去的是单字节还是多字节,本质都是二进制,我写入什么你就存什么不就好了,干嘛还要有限制。这是因为,Mysql对每个字段都定义了长度,比如varchar(10)表示10个字符,而不是字节,所以当存入数据的时候,mysql是做了解析的,这样才能知道字符串里有几个字符;当面对4字节字符的时候,mysql依然会以3字节的编码规则来解析,显然会解析出错的,因此就不让写入。

MySQL在5.5.3之后增加了这个utf8mb4的编码,mb4就是most bytes 4的意思,专门用来兼容四字节的unicode。好在 utf8mb4 是 utf8 的超集,除了将编码改为 utf8mb4 外不需要做其他转换。当然,为了节省空间,一般情况下使用 utf8 也就够了。

utf8 是 Mysql 中的一种字符集,只支持最长三个字节的 UTF-8 字符,可能是因为 Mysql 刚开始开发那会,Unicode 还没有4字节的字符。至于后续的版本为什么不对 4 字节长度的 UTF-8 字符提供支持,应该是为了向后兼容性的考虑,还有就是4字节字符确实很少用到。

2、为什么读取的时候要区分utf8和utf8mb4

按理说,我读取的都是二进制,不管是三字节还是四字节,我自己来展示,为什么在读取 utf8mb4 字段的时候,我使用 utf8 的连接得到的是乱码,使用 utf8mb4 连接得到的是正常的。实际上我的电脑是能展示四字节字符的。

因为mysql有个连接器组件,它处于客户端和服务器之间,用于字符集的转换。

现在有一个字段name,为了兼容emoj表情,字段设置为utf8mb4,在写入的时候数据库连接设置了charset=utf8mb4,因此可以正常写入;在读取的时候数据库连接设置charset=utf8,于是读出来展示的时候是乱码,如果改成charset=utf8mb4,读出来就能正常展示,那就是说,utf8的连接读到的结果并不是真实的数据,而是经过了连接器的转换,它将utf8mb4转换成了utf8,四字节字符被转换成了三字节,自然就是乱码。

那么,为什么要有这个转码的过程呢?

那是因为mysql支持很多的字符编码。

mysql> show character set;
+----------+-----------------------------+---------------------+--------+
| Charset  | Description                 | Default collation   | Maxlen |
+----------+-----------------------------+---------------------+--------+
| big5     | Big5 Traditional Chinese    | big5_chinese_ci     |      2 |
| dec8     | DEC West European           | dec8_swedish_ci     |      1 |
| cp850    | DOS West European           | cp850_general_ci    |      1 |
| hp8      | HP West European            | hp8_english_ci      |      1 |
| koi8r    | KOI8-R Relcom Russian       | koi8r_general_ci    |      1 |
| latin1   | cp1252 West European        | latin1_swedish_ci   |      1 |
| latin2   | ISO 8859-2 Central European | latin2_general_ci   |      1 |
| swe7     | 7bit Swedish                | swe7_swedish_ci     |      1 |
| ascii    | US ASCII                    | ascii_general_ci    |      1 |
| ujis     | EUC-JP Japanese             | ujis_japanese_ci    |      3 |
| sjis     | Shift-JIS Japanese          | sjis_japanese_ci    |      2 |
| hebrew   | ISO 8859-8 Hebrew           | hebrew_general_ci   |      1 |
| tis620   | TIS620 Thai                 | tis620_thai_ci      |      1 |
| euckr    | EUC-KR Korean               | euckr_korean_ci     |      2 |
| koi8u    | KOI8-U Ukrainian            | koi8u_general_ci    |      1 |
| gb2312   | GB2312 Simplified Chinese   | gb2312_chinese_ci   |      2 |
| greek    | ISO 8859-7 Greek            | greek_general_ci    |      1 |
| cp1250   | Windows Central European    | cp1250_general_ci   |      1 |
| gbk      | GBK Simplified Chinese      | gbk_chinese_ci      |      2 |
| latin5   | ISO 8859-9 Turkish          | latin5_turkish_ci   |      1 |
| armscii8 | ARMSCII-8 Armenian          | armscii8_general_ci |      1 |
| utf8     | UTF-8 Unicode               | utf8_general_ci     |      3 |
| ucs2     | UCS-2 Unicode               | ucs2_general_ci     |      2 |
| cp866    | DOS Russian                 | cp866_general_ci    |      1 |
| keybcs2  | DOS Kamenicky Czech-Slovak  | keybcs2_general_ci  |      1 |
| macce    | Mac Central European        | macce_general_ci    |      1 |
| macroman | Mac West European           | macroman_general_ci |      1 |
| cp852    | DOS Central European        | cp852_general_ci    |      1 |
| latin7   | ISO 8859-13 Baltic          | latin7_general_ci   |      1 |
| utf8mb4  | UTF-8 Unicode               | utf8mb4_general_ci  |      4 |
| cp1251   | Windows Cyrillic            | cp1251_general_ci   |      1 |
| utf16    | UTF-16 Unicode              | utf16_general_ci    |      4 |
| utf16le  | UTF-16LE Unicode            | utf16le_general_ci  |      4 |
| cp1256   | Windows Arabic              | cp1256_general_ci   |      1 |
| cp1257   | Windows Baltic              | cp1257_general_ci   |      1 |
| utf32    | UTF-32 Unicode              | utf32_general_ci    |      4 |
| binary   | Binary pseudo charset       | binary              |      1 |
| geostd8  | GEOSTD8 Georgian            | geostd8_general_ci  |      1 |
| cp932    | SJIS for Windows Japanese   | cp932_japanese_ci   |      2 |
| eucjpms  | UJIS for Windows Japanese   | eucjpms_japanese_ci |      3 |
+----------+-----------------------------+---------------------+--------+
40 rows in set

collation为排序规则,Maxlen为最大字节数。

不同的编码规则,会得到不同的二进制数,因此正确的编码转换是必要的。

查看当前的编码

mysql> show variables like '%char%';
+--------------------------+--------+
| Variable_name            | Value  |
+--------------------------+--------+
| character_set_client     | utf8   |
| character_set_connection | utf8   |
| character_set_database   | utf8   |
| character_set_filesystem | binary |
| character_set_results    | utf8   |
| character_set_server     | utf8   |
| character_set_system     | utf8   |
| character_sets_dir       |        |
+--------------------------+--------+

设置当前连接的编码,只针对此连接有效

mysql -h xxxxxx.mysql.rds.aliyuncs.com -u xxxxxx -p xxxxxxmysql> set names gbk;mysql> show variables like '%char%';
+--------------------------+--------+
| Variable_name            | Value  |
+--------------------------+--------+
| character_set_client     | gbk    |
| character_set_connection | gbk    |
| character_set_database   | utf8   |
| character_set_filesystem | binary |
| character_set_results    | gbk    |
| character_set_server     | utf8   |
| character_set_system     | utf8   |
| character_sets_dir       |        |
+--------------------------+--------+

这个命令会同时修改character_set_client, character_set_connection, character_set_results

我们在接数据库的时候设置的charset=utf8在内部就是调用的set names utf8

所以,代表客户端的编码有三个,这三个编码基本是一致的。其他的都是服务端的的编码。

character_set_client 客户端

character_set_connection 连接器

character_set_results 返回的结果集

既然是一样的,为什么客户端要搞三个配置呢,这就要从数据传输的流程上来看。

连接器:连接客户端与服务端,进行字符集的转换。

连接器的工作流程:

请求

character_set_client --> character_set_connection -->character_set_server

响应

character_set_server --> character_set_connection --> character_set_results

图示

在这里插入图片描述


http://chatgpt.dhexx.cn/article/qIUBOctW.shtml

相关文章

What is UTF-8?

分享一个大牛的人工智能教程。零基础!通俗易懂!风趣幽默!希望你也加入到人工智能的队伍中来!请点击人工智能教程 UTF-8 is a variable-width character encoding standard that uses between one and four eight-bit bytes to re…

图解unicode、utf8和utf8mb4

字符集和字符编码 字符集(CCS: Coded Character Set): 就是一个表格,表示每个字符对应数字(通常用16进制表示),比如unicode字符集中,数字1对应的就是U00031,字母a对应的…

UTF-8

UTF-8编码规则 UTF-8是Unicode的一种实现方式,也就是它的字节结构有特殊要求,所以我们说一个汉字的范围是0X4E00到0x9FA5,是指unicode值,至于放在utf-8的编码里去就是由三个字节来组织,所以可以看出unicode是给出一个…

MySQL 数据库字符集 utf8 和 utf8mb4 的区别

MySQL 的 utf8 实际上不是真正的 UTF-8。utf8 只支持每个字符最多三个字节,而真正的 UTF-8 是每个字符最多四个字节。 MySQL 一直没有修复这个 bug,他们在 2010 年发布了一个叫作 utf8mb4 的字符集, 绕过了这个问题。当然,他们并…

utf8和utf8mb4的区别

1. 基础知识 1.1 bit , byte , word 字 word 字节 byte (B) 位 bit (b) 1.2 单位换算 1字节 8位(1 byte 8bit) 1字 2字节(1 word 2 byte) 一个汉字 2字节 中文标点 三个字节 一个英文字母 一个字节 英文标点 一个字节 Em…

简单明了!utf8和utf8mb4的区别

一、简介 MySQL在5.5.3之后增加了这个utf8mb4的编码,mb4就是most bytes 4的意思,专门用来兼容四字节的unicode。utf8mb4是utf8 的超集,除了将编码改为utf8mb4外不需要做其他转换。当然,为了节省空间,一般情况下使用u…

浅谈uf8mb4字符集

要在 Mysql 中保存 4 字节长度的 UTF-8 字符,需要使用 utf8mb4 字符集(mb4就是most bytes 4的意思,专门用来兼容四字节的unicode),但只有 5.5.3 版本以后的才支持。 为了获取更好的兼容性,应该总是使用 utf…

学习笔记4-K均值聚类算法

K-均值聚类的一般流程 (1)收集数据:可以使用任何方法收集数据 (2)准备数据:需要数值型数据来计算距离,也可以将标称型数据映射为二值型数据再用于距离计算 (3)分析数据…

【吴恩达机器学习-笔记整理】k-means(k-均值聚类算法)

目录: 🌵🌵🌵前言一、应用二、k-means1、参数:2、过程3、应用4、优化目标5、随机初始化6、聚类数量的选择 ❤️❤️❤️忙碌的敲代码也不要忘了浪漫鸭! 🌵🌵🌵前言 ✨你好…

25.K-均值算法的介绍及实现过程

主要内容 K-均值算法的介绍K-均值算法的实现过程K-均值算法的具体例子实现过程 一、K-均值算法的介绍 K-均值(K- means) ** 是最普及的聚类算法**,算法接受一个未标记的数据集,然后将数据聚类成不同的组 聚类算法 是无监督学习…

K-means(K均值聚类算法)算法笔记

K-means(K均值聚类算法)算法笔记 K-means 算法,是比较简单的无监督的算法,通过设定好初始的类别k,然后不断循环迭代,将给定的数据自动分为K个类别。事实上,大家都知道K-means是怎么算的&#x…

K-近邻算法讲解以及实战

1.概述 邻近算法,或者说K最近邻(KNN,K-NearestNeighbor)分类算法是数据挖掘分类技术中最简单的方法之一。所谓K最近邻,就是k个最近的邻居的意思,说的是每个样本都可以用它最接近的k个邻居来代表。Cover和Hart在1968年提出了最初的…

第十五课.K均值算法

目录 K均值算法原理K均值算法的改进:K-meansnumpy实现K-means K均值算法原理 K均值(K-means)算法属于无监督学习中的聚类算法;聚类是根据样本特征向量之间的相似度或距离,将样本数据划分为若干个样本子集,…

K均值与K近邻算法简析

回顾了一下机器学习的简单算法。 原文链接:https://blog.csdn.net/zll0927/article/details/17000675 K-Means介绍 K-means算法是聚类分析中使用最广泛的算法之一。它把n个对象根据他们的属性分为k个聚类以便使得所获得的聚类满足:同一聚类中的对象相似度…

聚类算法、无监督学习、K均值算法及其优化函数

聚类算法 无监督学习:将无标签样本分为不同的两类或者多类,称为聚类算法 K均值算法 K均值算法是一个迭代算法,共两个步骤 1.簇分配:遍历图中每个样本,根据每个样本点离那个聚类中心近,从而将该样本点分配…

K-means算法-综合整理

A 主要流程 a 随机初始化k个点作为簇质心 b 计算每个点与质心距离(常用欧式距离和余弦距离),并将其分配给最近 的质心对应的簇中 c 重新计算每个簇的质心,更新为所有点的平均值 d 反复迭代b-c步骤,直到达到某个终止条…

K均值聚类算法(Kmeans)讲解及源码实现

K均值聚类算法(Kmeans)讲解及源码实现 算法核心 K均值聚类的核心目标是将给定的数据集划分成K个簇,并给出每个数据对应的簇中心点。算法的具体步骤描述如下。 数据预处理,如归一化、离群点处理等。随机选取K个簇中心,记为 μ 1 ( 0 ) , μ 2…

K-means算法详解及实现

文章目录 一、原理和流程1、原理2、流程 二、K-means中常用的到中心距离的度量有哪些三、K-means中的k值如何选取1、手肘法2、轮廓系数法3、总结 四、代码实现五、其他问题的解答References 主要的KMeans算法的原理和应用,在学习典过程中,我们要带着以下…

K-近邻算法全面解析

1 K-近邻算法简介 K-近邻(K-Nearest Neighbor,KNN),采用的是测量不同特征值之间距离的方法进行分类。对当前待分类样本的分类,需要大量已知分类的样本的支持,因此KNN是一种有监督学习算法。 2 K-近邻算法的三要素 距离度量、K…

k-means clustering algorithm,K均值算法

k-means clustering algorithm K均值聚类算法:需要分成K类,K是需要自己指定的 举例: 指定K,需要分成K类。 此例中:K为2选取K个点作为聚类中心 ,一般的,K为已有的点。 此例子:中为…