MYSQL(8.0版本及以上)- utf8mb3,utf8mb4 和utf8的含义和由来

官方文档:MySQL 8.0 Reference Manual: 10.9.2 The utf8mb3 Character Set (3-Byte UTF-8 Unicode Encoding)


首先,上结论:

  • 国际上的UTF-8,在MySQL中,对标的是uft8mb4
  • 在MySQL中,实际只有utf8mb4utf8mb3。至于uft8,在 V8.0 还是指代的utf8mb3,未来的会变为uft8mb4
    译者注mb3 maximun of 3 bytes per multibyte character.

国际上的UTF-8简介
Java Unicode编码 及 Mysql utf8 utf8mb3 utf8mb4 的区别与utf8mb4的过滤 ——苍枫露雨

UTF-8(8-bit Unicode Transformation Format) 是一种针对Unicode的可变长度字符编码,也是一种前缀码。它可以用来表示Unicode标准中的任何字符,且其编码中的第一个字节仍与ASCII兼容——这使得原来处理ASCII字符的软件无须或只须做少部分修改 即可继续使用。因此,它逐渐成为电子邮件、网页及其他存储或发送文字的应用中,优先采用的编码。

UTF-8使用1~4个字节为每个字符编码(2003年11月UTF-8被RFC 3629重新规范,只能使用原来Unicode定义的区域,U+0000到U+10FFFF,也就是说最多四个字节):

  • 128个US-ASCII字符只需1个字节编码(Unicode范围由U+0000至U+007F)。
  • 带有附加符号的拉丁文、希腊文、西里尔字母、亚美尼亚语、希伯来文、阿拉伯文、叙利亚文及它拿字母则需要2个字节编码(Unicode范围由U+0080至U+07FF)。
  • 基本多文种平面/BMP, Basic Multilingual Plane:字符(这包含了大部分常用字,例如CJVK常用字字符集 —— Chinese, Japanese, Vietnam, Korean)使用3个字节编码(Unicode范围由U+0800至U+FFFF)。
  • Unicode 辅助平面/Supplementary Multilingual Plane:使用极少,字符使用4个字节编码(Unicode范围由U+10000至U+10FFFF,主要包括不常用的CJK字符, 数学符号, emoji表情等)。

具体来讲是这样的:

uft8mb3
  • 支持&仅且支持BMP characters(不支持supplementary characters
  • 每个multibyte-character,都不多于3个bytes
uft8mb4
(MySQL的)utf8utf8mb3的别名:
  • MySQL里,utf8的(命名)是隐式的,等价于utf8mb3,但是但从名称上是看不出最大字符数的。
    • 好消息是MySQL在未来会改正uft8的命名:“在未来的MySQL版本中会删除utf8mb3,请改用utf8mb4。虽然utf8目前是utf8mb3的别名,但在未来某个时候,utf8将指代utf8mb4。为了避免对utf8的含义产生歧义,可以考虑直接把字符集引用指定为utf8mb4,而不是utf8。”

附注:

1. 一点关于MySQL的历史“ :

- 为什么MySQL开发者把utf8鬼改了?从提交的日志里,我们应该能推测出来。
  • MySQL从Version 4.1开始支持utf8。彼时,现行utf8标准RFC 3629没发布,老版本RFC 2279最多还支持6 bytes/Charactor呢。2002年3月28日,在the first pre-pre-relase version of MySQL4.1里,MySQL开发人员码入了RFC 2279

  • 在2002年9月MySQL的源代码上,出现了一个神秘的篡改,自此utf8的一个character最多支持3 byte sequences only ,即每个character短了1 byte。

  • 谁改的?为什么?无从得知。在MySQL改用Git那会,日志好像丢了原作者的名,(MySQL之前和Linux一样,kernel用的BitKeeper),从2003年9月前后的mailing list里,现在找不到更改源代码的注释。
    但我能猜啊!
    • 时间回到2002年,那会用户能体验MySQL的speed boost功能,假如保证table里每一行的bytes一样,即text column是’CHAR’类型(牺牲储存space换运行speed)。
      在这之后的某个时间,MySQL开发人员开始尝试utf8,请注意那会它还是 6 bytes/character,他应该犹豫了:一个 CHAR(1) 会占用6 bytes;那么一个CAHR(2)就占12 bytes,依次类推。

    • 我们要知道:那个刚开始的,即没有被发布的MySQL版本,是没鬼改的utf8的。它的官方文档甚至都写好了。
      但是明显的,某个MySQL开发员工(合作某个businessperson)十分关注一两个要这样做的客户:

      • 选出CHAR列 + 然后utf8编码它们。(CHAR格式在今天看是个古董,但在当时,MySQL靠它能运行地更快。自打2005年后它就不怎么地了)
    • 我推测,这个MySQL开发员工改了初版utf8的MySQL,想帮助用户兼顾空间和速度。

    • 结果是赔了夫人又折兵。一方面,想要speed和space的用户都失算了,因为utf8CHAR类型的字段,该大的还是大,该慢的还是慢。另一方面,当初要给MySQL添加utf8的开发员也是瞎折腾了一趟,因为鬼改版utf8 MySQL “?”(emoji表情)都存不了。

    • 自打鬼改版的utfmb3MySQL发布那一刻,就再也改不了了:总不能强迫每一个用户从头再搭一遍数据库吧!好不容易在2010年MySQL支持了完整版的utf8,却搞了一个奇葩的名字utf8mb4。”

2 有人吐槽说“或许,在整个互联网界,MySQL的‘utf8’定义都没人吊。”

Adam Hooper 在《In MySQL, never use “utf8”. Use “utf8mb4”.》吐槽:“

  • MySQL在命名上是渣渣
    • MySQL的‘uft8mb4’里每个character占用4 bytes,这个标准是everybody!everybody!everybody!在everywhere!everywhere!everywhere!都用的,MySQL应该把它叫做‘utf8’。
    • MySQL的‘uft8mb3’里每个character占用3 bytes,nobody!nobody!nobody!在anywhere!anywhere!anywhere!用:它应该被叫做‘utf8mb3’。
      或许,在整个互联网界,MySQL的‘utf8’定义都没人吊。”
  • 41
    点赞
  • 88
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值