MySQL如何存储emoji表情?👨‍💻🤣

1,554 阅读5分钟

0 写在开始之前

就目前自身的专业技能而言,不敢自称为一个专业技术人员,那就姑且自称为软件从业人员吧。 工作中经常会遇到一下场景:

同事:Mysql可以存储表情吗?

我:当然可以!这你都不知道?

同事:那你帮我弄一下,我怎么插不进去!

我:。。。你自己搞(我也不会)

每次发生这种情况的时候总是无比的尴尬,究其原因一般有两种情况:

  • 对知识一知半解,正所谓知其然不知其所以然
  • 以前确实查过这个知识,但是后来又忘了

为了尽量避免这种情况经常发生,决定在博客上养成一个对所学知识归档整理的习惯。一方面可以将学到的知识记录下来,以便日后可以复习巩固(好记性不如烂笔头);另一方面可以算是一个自己学习道路上的见证(方便以后装B)。

1 前言

百度百科中关于emoji表情的介绍如下:

最早由栗田穰崇(Shigetaka Kurita)创作,并在日本网络及手机用户中流行。

苹果公司发布的iOS 5输入法中加入了emoji后,这种表情符号开始席卷全球,emoji已被大多数现代计算机系统所兼容的Unicode编码采纳,普遍应用于各种手机短信和社交网络中。

从中可以发现,emoji表情其实更我们使用的其他文字一样,都可以用Unicode编码。

所以在进入正题之前,需要先了解一下Unicode字符集和UTF-8的内容。

2 Unicode

什么是Unicode?

人类语言需要按照一定规则转换为二进制编码才能够被计算机所识别,这个转换规则的映射表就是字符集

Character Set,例如最常见的ASCII码,其主要是为了表示英文字符而设计的,无论是最初用7个bit表示的版本还是后来用8个bit表示的版本都远远不够表示全世界的字符,所以会出现例如GBK等每个国家自己的字符集。

各国有各国的标准,难免会出现冲突,处理起来也很繁杂,所以Unicode出现了,Unicode把所有语言都统一到了一套编码里面。

Unicode怎么来表示字符呢?

Unicode只是一个字符集,为世界上每种语言中的每个字符设定了统一并且唯一的码位 (code point)。在表示一个Unicode的字符时,通常会用“U+”然后紧接着一组十六进制的数字来表示这一个字符。一个emoji表情也是一个字符,所以也可以用一个Unicode表示,如下:

UnicodeU+1F600U+1F601U+1F602U+1F603U+1F604
字符😀😁😂😃😄

Unicode来表示世界上所有的字符需要几个字节呢?

说起这个问题,就需要聊聊Unicode的编码方案了。最容易想到的做法就是让所有的字符都用定长的字节数来储存,UTF-32就是这周方案,UTF-32规定一个字符使用四个字节存储,也就是 32 位,这样就能涵盖现有 Unicode 包含的所有字符。这样虽然简单,但是缺点也很明显,有的字符明明可以用一个字节来储存,却要用四个字节不是很浪费空间吗?

所以就出现了本文的主角,UTF-8这种变长的编码方式。

UTF-8

UTF-8 代表 8 位一组表示 Unicode 字符的格式,使用 1 - 4 个字节来表示字符,其编码规则如下:

U+ 0000 ~ U+ 007F: 0XXXXXXX
U+ 0080 ~ U+ 07FF: 110XXXXX 10XXXXXX
U+ 0800 ~ U+ FFFF: 1110XXXX 10XXXXXX 10XXXXXX
U+10000 ~ U+1FFFF: 11110XXX 10XXXXXX 10XXXXXX 10XXXXXX

UTF-8通过开头的标志位位数实现了变长。对于单字节字符,只占用一个字节,对于多字节字符也可以像UTF-32一样支持4个字节

2 MySQL如何存储emoji表情

知道了Unicode的知识后,可以发现只要MySQL支持Unicode就可以存储emoji表情了。

但事实是,如果将MySQL的字符集设置为UTF-8,是不支持插入emoji表情的

image-20220303170017995.png

这是为什么呢?

emoji表情是从U+1F300开始的,从Unicode编码规则中可以看出,这个范围是需要4个字节,而罪魁祸首就是M有SQL的UTF-8其实是一个假的UTF-8,他最多只能支持三个字节,在这种情况下,像这种需要四个字节的字符就无法存储了。

为了解决这个问题,MySQL在5.5.3之后增加了新的utf8mb4的编码,mb4就是most bytes 4的意思,专门用来兼容四字节的unicode。

所以,如果需要在MySQL中存储emoji表情,需要选定utf8mb4字符集。

image-20220303170053336.png

3 结语

好了,作为一个软件行业从业者,我的第一篇已经完成了,希望以后可以坚持这个习惯。

最后以著名足球解说员贺炜老师的金句作为结尾:

找到一个目标,明白自己想要往何处去,然后坚定不移的朝着这个方向努力。中间可能有挫折,可能会有一段时间的彷徨,但是不要忘记自己为什么出发。按照这样的状态往前走的话,也许不久之后抬起头来,你会发现已经把其他人甩开了很远。