一次搞清unicode、utf8和utf8mb4

nanjingfm · · 1409 次点击 · 开始浏览    置顶
这是一个创建于 的主题,其中的信息可能已经有所发展或是发生改变。

![image-20210226175522617](https://bbk-images.oss-cn-shanghai.aliyuncs.com/typora/20210226175522.png) # 字符集和字符编码 **字符集(CCS: Coded Character Set):** 就是一个表格,表示每个字符对应数字(通常用16进制表示),比如[unicode](https://www.unicode.org/charts/PDF/U0000.pdf)字符集中,数字1对应的就是`U+00031`,字母a对应的就是`U+00061`。 ![image-20210226175533944](https://bbk-images.oss-cn-shanghai.aliyuncs.com/typora/20210226175533.png) **字符编码(CEF:Character Encoding Form):** 因为计算机只认识`0`和`1`,所以计算机在存储`字母a`(`U+00031`)的时候,不能直接存储。所以就需要编码将`字母a`转换成`01`表示形式。对于`unicode`字符,`utf8`就是它的编码方案(如何`utf8`转换成`01`表示下文介绍)。 **字符:** 字符简单理解就是人类能(容易)看懂得符号。 比如对于汉字`严`,机器存储的是`11100100 10111000 10100101`,人类根本看不懂。转换成`unicode`表示方法是`U+4E25`,依然看不懂。 人类只能看懂`严`这个字符,三者之间的关系如下: ![image-20210226175546407](https://bbk-images.oss-cn-shanghai.aliyuncs.com/typora/20210226175546.png) 字符串到保存文件过程如下: ![image-20210226175558858](https://bbk-images.oss-cn-shanghai.aliyuncs.com/typora/20210226175558.png) # UTF-8编码 `严`这个字的`unicode`码是`U+4E25`(对应的二进制数字是`100111000100101`),而`utf8`编码之后是`11100100 10111000 10100101`,是不是很奇怪?两个二进制完全不一样,是因为`utf8`有一套编码规则。 ![image-20210226175616715](https://bbk-images.oss-cn-shanghai.aliyuncs.com/typora/20210226175616.png) ## UTF-8编码规则 `utf8` 最大的一个特点,就是它是一种`可变长`的编码方式。它可以使用`1~4`个字节表示一个符号,根据不同的符号而变化字节长度。 `utf8` 的编码规则很简单,只有二条: - 对于单字节的符号,字节的第一位设为`0`,后面7位为这个符号的 Unicode 码。因此对于英语字母,`utf8` 编码和 `ASCII` 码是相同的。 - 对于`n`字节的符号(`n > 1`),第一个字节的前`n`位都设为`1`,第`n + 1`位设为`0`,后面字节的前两位一律设为`10`。剩下的没有提及的二进制位,全部为这个符号的 `Unicode` 码。 下表总结了编码规则,字母`x`表示可用编码的位。 ``` Unicode符号范围 | UTF-8编码方式 (十六进制) | (二进制) --------------------+--------------------------------------------- 0000 0000-0000 007F | 0xxxxxxx 0000 0080-0000 07FF | 110xxxxx 10xxxxxx 0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx 0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx ``` `严`字的`Unicode`编码是`4E25`处于`0000 0800 - 0000 FFFF`这个范围里面,所以需要三个字节表示。 ![](https://bbk-images.oss-cn-shanghai.aliyuncs.com/typora/20210226212135.png) 哇塞,原来是这样 # utf8和utf8mb4 `utf8mb4`只是`mysql`特有的概念,原因是`mysql`在`5.5.3`之前,`Unicode`收录的字符还不是很多,(最大)3个字节足够存储,所以那时的`mysql`把`utf8`(alias of "`utf8mb3`")存储也设计为3字节存储。后来`Unicode`收录的字符更多了,扩张到4字节了(比如表情😁)。 MySQL也在`5.5.3`版本之后增加了这个`utf8mb4`的编码,`mb4`就是`most bytes 4`的意思,专门用来兼容四字节的`Unicode`。 MySQL官方网站也解释了`utf8mb3`和`utf8mb4`之间的关系。 [https://dev.mysql.com/doc/refman/8.0/en/charset-unicode-utf8mb4.html](https://dev.mysql.com/doc/refman/8.0/en/charset-unicode-utf8mb4.html) [https://dev.mysql.com/doc/refman/8.0/en/charset-unicode-utf8mb3.html](https://dev.mysql.com/doc/refman/8.0/en/charset-unicode-utf8mb3.html) # 总结 - `Unicode`是字符集,是符合和码点的映射表 - `utf8`是`Unicode`的一种最常见的字符编码方式(还有`utf16`、`utf32`) - `mysql`中`utf8`实际上是`utf8mb3`(最大存储3字节),`utf8mb4`最大可以存储4字节(大部分表情都要占用4字节,所以需要选择`utf8mb4`)

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1409 次点击  
加入收藏 微博
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传