Mysql 中的 utf-8

导读

问题:在用户评论中带有 emoji表情时,utf-8编码的数据库抛出异常


`Incorrect string value: ‘\xF0\x9F\x98\x83 <…’ for column ‘comment’ at row 1`

在网上找解决方案:将相关字段字符集设置为 utf-8mb4,然后问题解决。

疑问:在我的理解中, utf-8 是用来存储各国语言字符的,utf-8mb4 是难道是专门用来存储 emoji的?

字符集及编码简介

要明白这个问题,首先需要先了解什么是字符集及编码方式。

字符集(Character set)是多个字符的集合,字符编码是在字符集内用于比较字符的一套规则,即字符集的排序规则。

首先我们知道,计算机使用 01 存储信息。最早的计算机在设计时采用 8个比特(bit)作为一个字节(byte)。所以,一个字节能表示的最大的整数就是 255(二进制 11111111,十进制 255),0 -255 被用来表示大小写英文字母、数字和一些符号,

这个编码表被称为 ASCII编码,比如大写字母 A 的编码是 65,小写字母 z 的编码是 122

小技巧:键盘按住 alt + 对应 ASCII 码,输入相应字符

时代在进步,计算机的普及和发展导致新的问题出现,对于中文、日文等文字符号,ASCII字符集并不能满足,于是出现了 UNICODE字符集,

通过扩充比特位的方式,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。将字符转为二进制编码的规则就被称为编码方式。

UNICODE通常用两个字节表示一个字符。为什么是 2字节呢?可能是因为在 UNICODE早期,设计 Unicode的团队考查了世界上主要的文字之后,感觉用 2个字节也就是最多 65536个字符应该够用了,设定编码方式为 UCS2。但是后面出现了更多的字符(现在 Unicode包含了 12万 8千个字符),于是只能再使用 UCS4或 UTF-32将字符以 4字节保存。

问题看起来解决了,但是却有个问题:很多字符使用这种编码并不高效,如用 ASCII表示的 00000001用 UTF-32就会存储很多无必要的高比特位。为了解决这个问题,就出现了其他的非固定长度编码方式,也就是本文的主角 ———— UTF-8,最短的 UTF-8字符只需要使用 1个字节(同 ASCII),最长是 4个字节。UTF-8相比 UTF-32更加节约空间。在 UTF-8中,像“1”这样的字符占用 1字节,“💩”这样的 emoji占用 4字节。其他字符占用 2或者 3字节。更小的空间占用也意味着加载与传输速度会快更多。

MYSQL 中的“utf-8”

可以注意到,上文我提到一个例子:UTF-8中 “💩”占用 4字节。这就回到了本文一开始的问题:utf-8编码的数据库在存储 emoji表情时出错。

按照上述的介绍,应该是可以存进去的?但是我们看下 MYSQL文档上对其 utf-8字符编码的解释:


utf8是 utf8mb3 字符集的别名

  该 utf8mb3 字符集有以下特点:

      * 仅支持BMP字符(不支持增补字符)

      * 每个多字节字符最多需要三个字节

划重点:每个多字节字符最多需要三个字节,这就表明了 MYSQL中 utf-8并不是传统意义上的 utf-8。

我们再看下 utf-8mb4


该utfmb4字符集有以下特点:

    * 支持BMP和补充字符。

    * 每个多字节字符最多需要四个字节。

也就是说,对于 MYSQL来说,utf-8mb4(mb4即 most byte 4)才是真正意义上的 utf-8。当我们 MYSQL数据库的字符集编码为 utf-8

存储需要 4字节表示的 emoji表情时,自然会出错了。

后话

MYSQL为什么会用这种奇怪的方式来定义字符集编码,在网上找了许久的答案没有准确的说法,更多的是把它看作 MYSQL开发过程中的一个失误。

如果大家后续清楚了原因,也可以说出来一起交流下。

另外在寻找问题的过程中也了解到其他一些知识点,跟大家简单分享下:

  • MySQL可以使用对种字符集和检验规则来组织字符。MySQL服务器可以支持多种字符集,在同一台服务器,同一个数据库,甚至同一个表的不同字段都可以指定使用不同的字符集。相比 oracle等其他数据库管理系统,在同一个数据库只能使用相同的字符集,MySQL明显存在更大的灵活性。

  • 数据库设置字符集的排序规则,如 utf8_general_ciutf8_unicode_cigeneralunicode 代表的是排序规则,使用 general 更快速,使用 unicode 更精确(德语等比较特殊的语种使用),ci 即 case insensitive, 即“大小写不敏感”。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容