为什么不建议在MySQL中使用UTF8?

2022-03-09 08:30:06 浏览数 (1)

MySQL字符串编码集中有两套UTF-8编码实现:utf8和utf8mb4

如果使用utf8的话,存储emoji符号和一些比较复杂的汉字,繁体字就会出错。

1.关于字符集

字符是各种文字和符号的集合,包括了各个国家的文字,标点符号,表情,数字等。 字符集就是一系列字符的集合。字符集的种类比较多,每个字符集可以表示的字符范围通常不同,就比如说有些字符集是无法表示汉字的。

计算机只能存储二进制的数据,那么英文,汉字,表情等字符串应该如何存储呢?

我们要将这些字符和二进制的数据一一对应,比如说字符串“a”对应“01100001”,反之“01100001”对应“a”。我们将字符串对应二进制数据的过程称为“字符编码”,反之,二进制数据解析成字符的过程称为“字符解码”。

2.常见的字符集

常见的字符集有ASCII,GB2312,GBK,UTF-8…… 不同的字符集的主要区别在于: 可以表示的字符范围 编码方式

ASCII: 美国信息交换标准代码,是一套主要用于现代美国英语的字符集,但也是ASCII的局限性所在,由于当时计算机发展的雏形阶段,所以只有英语着一种语言。

ASCII字符集至今为止共定义了128个字符串,其中有33个控制字符,一个ASCII码长度是一个字节也就是8个bit,比如“a”对应的ASCII码是“01100001”,但是最高位的0仅仅作为校验码,其余7位使用0和1进行组合,所以ASCII字符集可以定义128个字符,后续又扩展得到了ASCII扩展字符集。ASCII扩展字符集使用8bits表示一个字符,所以可以定义256个字符

GB2312 GB2312字符集是一种对汉字友好的字符集,共收录6700多个汉字,基本上涵盖了绝大部分常用的汉字,然而并不支持绝大部分的生僻字和繁体字。对于英文字符也是1字节编码即可,对于非英文字符,需要2字节编码。

GBK GBK字符集可以看作是GB2312字符集的扩展,兼容了GB2312字符集,共收录了20000多个汉字。GBK中的k是汉语拼音Kuo Zhan(扩展)中的“Kuo”的首字母

GB18030 GB18030完全兼容上面两种字符集,纳入中国国内少数民族的文字,且收录了日韩文字,是目前为止最全面的汉字字符集,共收录了汉字70000多个。

Unicode & UTF-8 不同的字符集可以表示字符范围以及编码规则存在差异。这就导致了一个非常严重的问题:使用错误的编码方式查看一个包含字符的文件就会产生乱码现象。

若果使用UTF-8编码方式打开GB2312编码格式的文件就会出现乱码。 例如:“牛” GB2312编码后的十六进制数值为:“C5A3” 然而使用UTF-8解码得到:“ ţ ”

现在我们知道了乱码的本质:编码和解码时用了不同或者不兼容的字符集。

这时候和编程语言一样的想法诞生了:“如果我们能有一种字符集将世界上所有的字符都纳入其中就好了!”

于是,Unicode就此诞生。

Unicode字符集中包含了世界上几乎所有的已知的字符,不过,Unicode字符集并没有规定如何存储这些字符串(也就是如何使用二进制数据表示这些字符)

于是就有了UTF-8,类似的还有UTF-16,UTF-32 UTF-8使用1-4个字节为每个字符编码,UTF-16使用2或4个字节为每个字符编码,UTF-32固定4个字节为每个字符编码。

3.My SQL字符集

MyS QL支持很多字符编码的方式,比如UTF-8、GB2312、GBK、BIG5

通过命令 SHOW CHARSET 来查看 通常我们都使用UTF-8作为默认的字符编码方式,但是有一个小坑

MySQL字符编码集中有两套UTF-8编码实现:

utf8:utf编码只支持1-3个字节。在utf8编码中,中文占3个字节,其他数字、英文、符号占一个字节。但emoji符号占4个字节,一些比较复杂的文字、繁体字也是4个字节。

utfmb4:UTF-8的完整实现,可以说是正版!最多支持4个字节表示字符,因此,可以用来存储emoji符号

4.演示

环境:MySQL 5.7 数据库CHARSET:utf8

代码语言:javascript复制
CREATE TABLE `user` (
  `id` varchar(66) CHARACTER SET utf8mb4 NOT NULL,
  `name` varchar(33) CHARACTER SET utf8mb4 NOT NULL,
  `phone` varchar(33) CHARACTER SET utf8mb4 DEFAULT NULL,
  `password` varchar(100) CHARACTER SET utf8mb4 DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

当插入以下数据报错:

代码语言:javascript复制
INSERT INTO `user` (`id`, `name`, `phone`, `password`)
VALUES
 ('A00003', 'guide哥 表情—————-这里已经显示不出来了)

报错信息如下:

代码语言:javascript复制
Incorrect string value: 'xF0x9Fx98x98xF0x9F...'
 for column 'name' at row 1

0 人点赞