7

It would seem that using the ASCII charset for most fields and then specify utf8 only for the fields that need it would reduce the amount of I/O the database must perform by 100%.

Anyone know if this is true?

Update: The above was not really my question. I should have said: use Latin for the default character set and then only specify utf8mb4 only for the fields that need it. The thinking being that: using 1 byte vs 2 bytes should improve I/O by 100%. Sorry for the confusion.

4

2 回答 2

13

简短的回答:不值得担心。

长答案

两个问题:

  • 速度:

将两种编码与相应的 _bin(ascii_bin 或 utf8_bin)COLLATION进行比较就像比较字节一样简单——因此没有显着差异。其他排序规则可能不同,ascii 更快。 但是与获取行等的工作量相比,差异是微不足道的。

  • 空间:

Ascii 是 utf8 的子集。utf8 只为每个 ascii 字符存储 1 个字节,就像 ascii 一样。所以,没有空间差异。(西欧的重音字母需要 1 字节 latin1 或 2 字节 utf8;因此不兼容且大小不同。)空间导致缓存,从而导致性能略有不同。

对于英文文本,节省 0%。对于欧洲人来说,latin1 只会节省几个百分点;对于世界上大多数其他地方,utf8 是唯一可行的解​​决方案。对于中文和表情符号,utf8mb4 是必须的。

  • 临时表

在某些情况下,字符串占用的空间会扩展到潜在的最大值。 country_code CHAR(2) CHARACTER SET ...ascii 将占用 2 个字节;utf8 为 6 个字节。

底线:

对国家代码、十六进制、邮政编码、uuid、md5s 等使用 ascii。如果您要走向国际,和/或需要表情符号,那么将您的“字符串”设为 utf8mb4。但是这样做是因为它是“正确的”,而不是因为你会神奇地获得更快的速度;你不会的。并且在您创建表格时执行此操作;就是以后改的坑。

于 2018-07-23T23:51:59.687 回答
8

@RickJames 是对的,您不必担心通过选择 ASCII 或 utf8 而不是 utf8mb4 来节省空间。

utf8 和 utf8mb4 是变长字符编码。维基百科中的这张表说明了字符如何根据编码的值自动占用 1、2、3 或 4 个字节。如果设置了一个字节的高位,则该字符使用一个额外的字节,最多 4 个字节。

在此处输入图像描述 维基百科的文章清楚地解释了它:

前 128 个字符(US-ASCII)需要一个字节。接下来的 1,920 个字符需要两个字节来编码,这涵盖了几乎所有拉丁字母表的其余部分,以及希腊语、西里尔语、科普特语、亚美尼亚语、希伯来语、阿拉伯语、叙利亚语、Thaana 和 N'Ko 字母,以及组合变音符号分数。基本多语言平面的其余字符需要三个字节,其中包含几乎所有常用字符,包括大多数中文、日文和韩文字符。Unicode 其他平面中的字符需要四个字节,其中包括不太常见的 CJK 字符、各种历史文字、数学符号和表情符号(象形符号)。

您无需做任何事情来选择单字节与多字节模式。这就是编码的工作方式。每个字符自动使用它需要的字节数,仅此而已。

因此,使用 utf8 优于 utf8mb4 没有任何优势,使用 ASCII 也没有任何优势,除非您需要限制字符串中允许的字符。

值得一提的是,MySQL 调用的字符集“utf8”是 utf8mb3 的别名,它只是 UTF8 编码的前三个字节的实现。MySQL 服务器团队博客 ( https://mysqlserverteam.com/mysql-8-0-when-to-use-utf8mb3-over-utf8mb4/ ) 说 utf8mb4 更快,至少考虑到 MySQL 8.0 和 utf8mb3 的性能改进应视为已弃用。MySQL 8.0.11 发行说明说 utf8 将在 MySQL 的某些未来版本中重新定义为 utf8mb4 的别名。

于 2018-07-24T16:20:57.653 回答