广告
返回顶部
首页 > 资讯 > 数据库 >永远不要在 MySQL 中使用 utf8,使用 utf8mb4 作为代替
  • 59
分享到

永远不要在 MySQL 中使用 utf8,使用 utf8mb4 作为代替

utf8mb4mysql 2022-11-16 18:11:14 59人浏览 佚名
摘要

今天的错误:我试图在 MariaDB 「utf8」 编码的数据库中存储一个 UTF-8 字符串,Rails 出现了一个奇怪的错误:Incorrect string value: ‘\xF0\x9F\x98\x8

今天的错误:我试图在 MariaDB 「utf8」 编码的数据库中存储一个 UTF-8 字符串,Rails 出现了一个奇怪的错误:

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

这是一个 UTF-8 客户端和一个 UTF-8 服务器,位于具有 UTF-8 排序规则的 UTF-8 数据库中。 字符串「? <…」是有效的 UTF-8。

但问题是:Mysql 的「utf8不是 UTF-8

「utf8」编码仅支持每个字符三个字节。 真正的 UTF-8 编码——包括你在内的每个人都在使用——每个字符最多需要四个字节。

mysql 开发人员从未修复过这个错误。 他们在 2010 中发布了一个解决方法:一个名为「utf8mb4」的新字符集。

当然,他们从来没有宣传过这个(可能是因为这个错误太尴尬了)。 现在,网络上的指南建议用户使用「utf8」。 所有这些指南都是错误的。

简而言之:

  • Mysql「utf8mb4」表示「UTF8」。

  • MySQL「utf8」表示「专有字符编码」。 这种编码不能编码许多 Unicode 字符。

我将在这里做一个全面的声明:所有 当前使用「utf8」的 MySQL 和 MariaDB 用户应该 实际上 使用「utf8mb4」。 没有人应该使用「utf8」。

什么是编码? 什么是 UTF-8?

Joel on Software 写了我最喜欢的介绍, 我来简述它。

计算机将文本存储为 1 和 0。 本段中的第一个字母存储为「01000011」,计算机绘制了「C」。 计算机分两步选择了「C」:

  1. 计算机读取「01000011」并确定它是数字 67。这是因为 67 被编码为「01000011」。

  2. 你的计算机在 Unicode字符集 中查找字符编号 67,发现 67 表示「C」。

当我输入「C」时,同样的事情发生在我身上:

  1. 我的电脑将「C」映射到 Unicode 字符集中的 67。

  2. 我的电脑 编码 67,将「01000011」发送到此 WEB 服务器。

字符集 是一个已解决的问题。 互联网上几乎每个程序都使用 Unicode 字符集,因为没有动机使用另一个字符集。

编码 更像是一种判断。 Unicode 有超过一百万个字符的插槽。 (「C」和「?」就是两个这样的字符。)最简单的编码 UTF-32 使每个字符占用 32 位。 这很简单,因为计算机多年来一直将 32 位组视为数字,而且它们真的很擅长。 但它没有用:这是浪费空间。

UTF-8 节省空间。 在 UTF-8 中,像「C」这样的常见字符占用 8 位,而像「?」这样的稀有字符占用 32 位。 其他字符占用 16 或 24 位。 像这样的博客文章在 UTF-8 中占用的空间大约是 UTF-32 中的四倍。 所以它的加载速度快了四倍。

你可能没有意识到,但我们的计算机在幕后同意使用 UTF-8。 如果他们没有,那么当我输入「?」时,你会看到一堆乱七八糟的随机数据。

MySQL 「utf8」 字符集与其他程序不一致。 当他们说「?」时,它就开始了。

一点 MySQL 历史

为什么 MySQL 开发人员让「utf8」无效? 我们可以通过查看提交日志来猜测。

MySQL 支持 UTF-8,因为 version 4.1

那是 2003 年——在今天的 UTF-8 标准之前,RFC 3629.

之前的 UTF-8 标准 RFC 2279 支持每个字符最多六个字节。 MySQL 开发人员于 2002 年 3 月 28 日在 [MySQL 4.1 的第一个预发布版本] (github.com/mysql/mysql-server/comm...) 中编写了 RFC 2279。

然后在 9 月对 MySQL 的源代码进行了一个神秘的单字节调整:「UTF8 现在最多可处理 3 字节序列。」

谁要求这个改变? 为什么? 我不知道。 2003 年 9 月左右的邮件列表中没有任何内容可以解释这一变化。 (RFC 2279 在 2003 年 11 月被宣布过时,为当前的 UTF-8 标准让路,RFC 3629。)

但我可以猜到为什么 MySQL 违反了标准。

早在 2002 年,如果用户可以保证表中的每一行都具有相同的内容,MySQL 就为用户提供了 速度提升 字节数。 为此,用户将文本列声明为「CHAR」。 「CHAR」列中的每条记录的值都具有相同数量的字符。 如果输入的字符太少,MySQL 会在末尾添加空格; 如果输入太多字符,MySQL 会截断最后一个字符。

当 MySQL 开发人员第一次尝试 UTF-8 时,其过去每个字符 6 个字节,他们可能会犹豫:一个 CHAR(1) 列需要 6 个字节; CHAR(2) 列将占用 12 个字节; 等等。

让我们明确一点:从未发布过的最初行为是正确的。 它有据可查并被广泛采用,任何了解 UTF-8 的人都会同意它是正确的。

但很明显,一个 MySQL 开发人员(或用户,或客户)担心他们会做两件事:

  1. 选择 CHAR 列。(CHAR 格式现在是一个遗物。当时,MySQL 使用 CHAR 列更快。从 2005 年开始,它就不是了。)

  2. 选择将这些 CHAR 列编码为「utf8」。

我的猜测是 MySQL 开发人员打破了他们的「utf8」编码来帮助这些用户:1)试图优化空间和速度的用户;
2) 忽略了对速度和空间的优化。

没有人是赢家。 想要速度和空间的用户仍然 错误地使用 「utf8」CHAR 字段,因为这些字段仍然比它们应有的更大和更慢。 而原本想要正确性的开发者使用「utf8」是错误的,因为它不能存储「?」。

一旦 Mysql 发布了这个无效的字符集,它就永远无法修复它:这将迫使每个用户重建数据库。MySQL 最终在 2010 ,发布了 UTF-8 的支持,有一个不同的名字:「utf8mb4」。

为何如此令人沮丧

显然这周我很沮丧。我的错误很难被找到,因为我被「uft8」这个名字所迷惑了。而且我并不是唯一一个,几乎我在网上找到的文章都将「uft8」吹捧为「UTF-8」。

「utf8」总是错误的。 它是一个专有的字符串集。它创造了新的问题,而且并没有解决它本来想要解决的问题。

我的总结

  1. 数据库系统有微妙的错误和怪异,你可以通过避免使用数据库系统来避免很多错误。

  2. 如果你需要一个数据库,请不要使用「MySQL」或者「MariaDB」。请使用 「 Postgresql 」。

  3. 如果你需要使用 「MySQL」或者「MariaDB」,千万不要使用「UTF-8」,当你想要用「UTF-8」的时候,总是使用「utf8mb4」,现在就 转换你的数据库 从而避免之后的麻烦。

您可能感兴趣的文档:

--结束END--

本文标题: 永远不要在 MySQL 中使用 utf8,使用 utf8mb4 作为代替

本文链接: https://www.lsjlt.com/news/173087.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 永远不要在 MySQL 中使用 utf8,使用 utf8mb4 作为代替
    今天的错误:我试图在 MariaDB 「utf8」 编码的数据库中存储一个 UTF-8 字符串,Rails 出现了一个奇怪的错误:Incorrect string value: ‘\xF0\x9F\x98\x8...
    99+
    2022-11-16
    utf8mb4 mysql
  • 为什么永远不要在MySQL中使用UTF-8
    这篇文章给大家介绍为什么永远不要在MySQL中使用UTF-8,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。最近我遇到了一个bug,我试着通过Rails在以“utf8”编码的MariaDB中保存一个UTF-8字符串,然后...
    99+
    2023-06-19
  • 记住:永远不要在 MySQL 中使用 UTF-8
    阅读本文大概需要 3.6 分钟。 译文:http://suo.im/4zBuvs 来自:http://ju.outofmemory.cn 最近我遇到了一个bug,我试着通过Rails在以“...
    99+
    2022-10-18
  • 在MySQL中为何不建议使用utf8
    目录何为字符集?有哪些常见的字符集?ASCIIGB2312GBKGB18030BIG5Unicode & UTF-8 编码mysql 字符集MySQL 字符编码集中有两套 UTF-8 编码实现:utf8 和 ut...
    99+
    2022-11-01
  • User这个词为什么不要在代码中使用
    今天给大家介绍一下User这个词为什么不要在代码中使用。文章的内容小编觉得不错,现在给大家分享一下,觉得有需要的朋友可以了解一下,希望对大家有所帮助,下面跟着小编的思路一起来阅读吧。当你意识到你在项目开始时做的轻量、简单的设想竟然完全错了时...
    99+
    2023-06-28
  • 为何不要在MySQL中使用UTF-8编码方式详解
    MySQL的UTF-8编码方式 MySQL 从 4.1 版本开始支持 UTF-8,也就是 2003 年,然而目前流行的UTF-8 标准(RFC 3629)是在此之后规定的。正因此,才造就了MySQL中的U...
    99+
    2022-10-18
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作