Code前端首页关于Code前端联系我们

mysql是否添加另一种utf8mb4数据类型而不是更新utf8?

terry 2年前 (2023-09-26) 阅读数 61 #数据库

作者:大宽宽

为什么MySQL在这个地方承诺2。接下来的内容只是一个猜测。

首先我们来说说utf8标准。早期用1到6个字节来表示一个字符。因此,在MySQL最早的实现中,字符是使用6个字节来实现的。这是正确的做法。然而,出于性能考虑,MySQL希望用户能够使用具有相同字符的列。换句话说,如果一个字符使用的字节数少于6个字节,则存储空间将被空符号填满。学过计算机的人都会明白,使用相同长度的字符利用数组索引值来查找数据会非常快。

较旧的 RFC2279 指定 UTF8 字符以 1 到 6 个字节进行编码。后来改为1到4。

正因为如此,MySQL甚至开发了一种“静态格式”存储结构,使用固定长度的数据来加速数据访问。 (不过这个东西只能用在MyISAM上,当时MySQL还没有抢占InnoDB)

15.2.3.1 静态(定长)表特性​dev.mysql.com

不过也简单看看,这样做太浪费空间了。大多数英文字符可以使用 UTF8 编码为 1 个字节,而中文和其他字符可以使用 3 个字节编码。 1Charater = 6Byte 的设计加上 21 世纪初存储并不便宜的事实会让任何看到它的人感到绝望。

好的,现在我们已经介绍了基础知识,让我们来谈谈历史。让我们回到2002年,MySQL计划在4.1版本中支持utf8。 4.1的早期开发版本最多使用6个字节来表示一个utf8字符,这是正确的。但MySQL不知道他脑子里在想什么。 2002 年 9 月 27 日,无特殊原因,它做出了这样的提交,强制 utf8 编码仅处理最多 3 个字节的序列。 mysql 额外加入一个 utf8mb4 数据类型,而不是原地升级 utf8?

参见:UTF8现在仅适用于最多3字节序列·mysql/mysql-server@43a506c

我找不到关于此事的任何因果关系,也找不到任何文章、讨论或相关内容信息。

但粗略猜测是MySQL当时想使用定长存储,但发现太浪费了,所以索性一下子把6改成了3。

在Unicode中,3个字节可以支持所有BMP(Basic Multilingual Plane)字符;但它不能支持SMP(补充多语言平面),包括表情符号(这是受影响最严重的区域)和一些不常见的CJK字符,一些不常见的符号等。对于正文(英语,各种欧洲语言,中文,日语......) , 3个utf8字节就够了。

然而多年以后,或许是苹果表情包的大力推广,大家发现MySQL的utf8其实并不是utf8。直到 2010 年,MySQL 版本 5.5.3 才引入了 utf8mb4(从现在起 utf8 的别名是“utf8mb3”)。这个变化是非常微妙的。更新大体介绍的时候完全没有提到,细节里只写了一行。也许是因为从 6 更改为 3 太愚蠢而您不想发布? mysql 额外加入一个 utf8mb4 数据类型,而不是原地升级 utf8?

参见:https://dev.mysql.com/doc/relnotes/mysql/5.5/en/news-5-5-3.html

这个问题问的是为什么utf8不升级。这很容易理解。大量数据库文件以utf8格式保存。如果“就地升级”,这意味着必须重新创建所有现有数据库文件。我了解所有关于数据的事情。如果MySQL真的这么做了,恐怕不会被谩骂,而是直接被判死刑。向 utf8mb4 的过渡缓慢是可以理解的。

顺便说一下。 RFC2279是UTF8的早期标准,规定UTF8字符为1到6个字节。这也是Mysql首先将UTF8字符设计为6字节的原因。但在 2003 年 11 月,发布了新的 RFC3629 标准,规定 UTF8 字符为 1 到 4 个字节,一年后 MySQL 才做出了那个愚蠢的承诺。历史真的很有趣。

从2002年到2019年,已经过去了17年。 MySQL 8.0刚刚发布,但utf8仍然是utf8mb3的别名。不知道这个因莫名决定而诞生的奇异物种何时会被彻底消灭。

Hello~mysql 额外加入一个 utf8mb4 数据类型,而不是原地升级 utf8?摘自MySQL8.0文档

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

热门