MySQL:不正確的字元串值
我在網頁中的某些字元上遇到了一些問題,我們在 UTF8 中經常遇到這些問題。
我正在使用 Debian 9 執行 MySQL 5.7。我的數據庫正在使用
utf8
字元集。今天在調試一個mysql查詢的時候,跑到
SHOW WARNINGS;
Message欄位中看到:Incorrect string value: '\xF0\x9D\x8C\x86' for column `xxxx`;
怎麼了?
最終,通過Google搜尋錯誤,我發現了幾篇文章,表明在 MySQL 中,
utf8
字元集是錯誤的/大腦受損,不應該使用。在它的替換中,應該使用
utf8mb4
字元集來代替。在MySQL 中,永遠不要使用“utf8”。使用“utf8mb4”
MySQL 的“utf8”不是 UTF-8。
“utf8”編碼僅支持每個字元三個字節。真正的 UTF-8 編碼——包括你在內的每個人都在使用——每個字元最多需要四個字節。
MySQL 開發人員從未修復過這個錯誤。他們在 2010 年發布了一個解決方法:一個名為“utf8mb4”的新字元集。
簡而言之:
MySQL 的“utf8mb4”表示“UTF-8”。
MySQL 的“utf8”表示“專有字元編碼”。這種編碼不能編碼許多 Unicode 字元。
我將在這裡做一個全面的聲明:所有目前使用“utf8”的 MySQL 和 MariaDB 使用者實際上應該使用“utf8mb4”。沒有人應該使用“utf8”。
原來 MySQL 的 utf8 字元集僅部分實現了正確的 UTF-8 編碼。它只能儲存由一到三個字節組成的 UTF-8 編碼符號;不支持佔用四個字節的編碼符號。
如上所示,這種行為可能會導致數據失去,但情況會變得更糟——它可能會導致安全漏洞。以下是一些範例,所有範例都是在發布此文章後發現的:
- WordPress < 3.6.1 中的 PHP 對象注入漏洞,導致與某些 WordPress 外掛結合遠端執行程式碼
- WordPress 4.1.2 中 Phabricator 儲存的 XSS 中的電子郵件身份驗證繞過
- Joomla 中的遠端命令執行!內容管理系統
TL;DR MySQL 的
utf8
編碼名稱很尷尬,因為它與正確的 UTF-8 編碼不同。它不提供完整的 Unicode 支持,這可能導致數據失去或安全漏洞。