在現代 Web 應用程序世界中,支持多種語言和字符集變得越來越重要。隨着全球化的興起,存儲和處理多語言數據的需求變得至關重要。MySQL 作爲最流行的關係數據庫管理系統之一,認識到了這一需求,並在其 8.0 版本中引入了 utf8mb4。在這篇文章中,我們將通過實際示例探討 utf8mb4 及其在 MySQL 8 中的優勢。
作者:Arunjith Aravindan
本文約 2000 字,預計閱讀需要 7 分鐘。
瞭解 utf8mb4
在深入探討 utf8mb4 的好處之前,我們先澄清一下 utf8mb4 代表什麼。在 MySQL 中,“utf8”是指支持 Unicode 字符集的字符編碼,每個字符最多使用三個字節。然而,MySQL 中原始的 utf8 實現並沒有涵蓋所有 Unicode 字符。另一方面,utf8mb4 是 utf8 的修改版本,它支持完整的 Unicode 字符集,包括表情符號和其他補充字符,每個字符最多使用四個字節。
MySQL 中原始的 utf8 實現僅支持基本多文種平面(BMP)中的字符,大約佔所有 Unicode 字符的 90%。另一方面,utf8mb4 支持整個 Unicode 字符集,包括表情符號和其他補充字符。它通過每個字符最多使用四個字節而不是 utf8 使用的三個字節來實現此目的。
下表顯示了 utf8 和 utf8mb4 之間的區別:
特徵 | UTF8 | utf8mb3 | utf8mb4 |
---|---|---|---|
每個字符的最大字節數 | 3 | 3 | 4 |
支持的字符 | 基本多文種平面 (BMP) | BMP | BMP + 輔助平面 |
MySQL 默認 | Yes | Yes | Yes(MySQL 8.0 開始) |
狀態 | 已棄用 | 已棄用 | 未棄用 |
注意:歷史上,MySQL 使用字符集 utf8 作爲 utf8mb3 的別名。但是,從 MySQL 8.0.28 開始,utf8mb3 僅在 SHOW 語句的輸出和信息架構表中引用該字符集時使用。未來,utf8 有望成爲 utf8mb4 的參考。爲了避免任何歧義,建議在引用該字符集時顯式指定 utf8mb4。
如您所見,utf8、utf8mb3 和 utf8mb4 之間的主要區別在於每個字符的最大字節數。 utf8 和 utf8mb3 只能存儲 BMP 中的字符,而 utf8mb4 還可以存儲補充平面(Supplementary Plane)中的字符。這意味着 utf8mb4 可以支持更廣泛的字符,包括表情符號、數學符號和其他特殊字符。
這三個字符集之間的另一個區別是它們在 MySQL 中的默認狀態。utf8 是 MySQL 5.7 及更早版本中的默認字符集,而 utf8mb3 是 MySQL 8.0 中的默認字符集。但是,utf8mb4 是 MySQL 8.0.28 及更高版本中的默認字符集。
最後,MySQL 8.0 中已棄用 utf8 和 utf8mb3。這意味着它們最終將從 MySQL 中刪除,因此建議使用 utf8mb4 代替。
因此,如果您需要存儲所有 Unicode 字符,包括表情符號和其他補充字符,那麼您應該使用 utf8mb4。但是,如果您只需要存儲 BMP 中的字符,那麼 utf8 可能就足夠了。
以下是使用 MySQL 表和查詢對 utf8 和 utf8mb4 進行比較的示例:
對比示例
MySQL 5.7
mysql> select version();
+-----------+
| version() |
+-----------+
| 5.7.42-46 |
+-----------+
Table
mysql> CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) CHARACTER SET utf8,
email VARCHAR(255) CHARACTER SET utf8
);
Query OK, 0 rows affected (0.03 sec)
mysql> show create table usersG
*************************** 1. row ***************************
Table: users
Create Table: CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) CHARACTER SET utf8 DEFAULT NULL,
`email` varchar(255) CHARACTER SET utf8 DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.01 sec)
在用戶表中插入三行數據,包括 emoji 表情符號。
mysql> INSERT INTO users (name, email) VALUES
('Arun Jith', '[email protected]'),
('Jane Doe', '[email protected]'),
('𝌆', '[email protected]');
ERROR 1366 (HY000): Incorrect string value: 'xF0x9Dx8Cx86' for column 'name' at row 3
mysql>
遇到的錯誤消息 ERROR 1366 (HY000): Incorrect string value: ‘xF0x9Dx8Cx86’ for column ‘name’ at row 3,
第 3 行的 name
字段的字符編碼存在問題。用戶表嘗試將 Unicode 字符 𝌆
插入 name
字段時發生錯誤。
mysql> INSERT INTO users (name, email) VALUES
('Arun Jith', '[email protected]'),
('Jane Doe', '[email protected]')
;
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0
MySQL 8.0
mysql> select version();
+-------------------------+
| version() |
+-------------------------+
| 8.0.33-0ubuntu0.22.04.2 |
+-------------------------+
Table
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) CHARACTER SET utf8,
email VARCHAR(255) CHARACTER SET utf8
);
mysql> show create table usersG
*************************** 1. row ***************************
Table: users
Create Table: CREATE TABLE `users` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL,
`email` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)
該表的 name
和 email
字段均使用 utf8mb3 字符集。這意味着該表可以存儲 BMP 中的所有字符,但不能存儲表情符號或其他補充字符。
Query
INSERT INTO users (name, email) VALUES
('Arun Jith', '[email protected]'),
('Jane Doe', '[email protected]'),
('𝌆', '[email protected]');
與前面的示例一樣的錯誤( ERROR 1366 (HY000): Incorrect string value: ‘xF0x9Dx8Cx86’ for column ‘name’ at row 3,
)。
mysql> INSERT INTO users (name, email) VALUES
-> ('Arun Jith', '[email protected]'),
-> ('Jane Doe', '[email protected]'),
-> ('𝌆', '[email protected]');
ERROR 1366 (HY000): Incorrect string value: 'xF0x9Dx8Cx86' for column 'name' at row 3
mysql> INSERT INTO users (name, email) VALUES
-> ('Arun Jith', '[email protected]'),
-> ('Jane Doe', '[email protected]')
-> ;
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0
此查詢將前兩行數據插入用戶表中。前兩行包含簡單的文本數據,而第三行包含emoji 表情符號。表情符號將無法正確存儲在數據庫中,因爲 utf8 字符集無法存儲 emoji 表情符號。
Output
mysql> SELECT * FROM users;
+----+-----------+----------------------+
| id | name | email |
+----+-----------+----------------------+
| 4 | Arun Jith | [email protected] |
| 5 | Jane Doe | [email protected] |
+----+-----------+----------------------+
2 rows in set (0.00 sec)
此查詢將從用戶表中選擇兩行。查詢的輸出將是用戶表中所有行的列表,包括每個用戶的 ID
、name
、email
。第三行有表情符號的無法存儲,插入時出錯,因爲 utf8 字符集無法存儲表情符號。
Table
爲了確保正確存儲表情符號,讓我們使用 utf8mb4 字符集創建表列。之後,我們可以繼續檢查表情符號插入是否正確。
mysql> CREATE TABLE users (
-> id INT AUTO_INCREMENT PRIMARY KEY,
-> name VARCHAR(255) CHARACTER SET utf8mb4,
-> email VARCHAR(255) CHARACTER SET utf8mb4
-> );
Query OK, 0 rows affected (0.03 sec)
mysql> show create table usersG
*************************** 1. row ***************************
Table: users
Create Table: CREATE TABLE `users` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,
`email` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)
Query
INSERT INTO users (name, email) VALUES
('Arun Jith', '[email protected]'),
('Jane Doe', '[email protected]'),
('𝌆', '[email protected]');
mysql> INSERT INTO users (name, email) VALUES
-> ('Arun Jith', '[email protected]'),
-> ('Jane Doe', '[email protected]'),
-> ('𝌆', '[email protected]');
Query OK, 3 rows affected (0.01 sec)
Records: 3 Duplicates: 0 Warnings: 0
該表對 name
和 email
列均使用 utf8mb4 字符集。這意味着該表可以存儲完整 Unicode 字符集中的所有字符,包括 emoji 表情符號和其他補充字符。
此查詢將三行數據插入用戶表中。前兩行包含簡單的文本數據,而第三行包含表情符號。表情符號將正確存儲在數據庫中,因爲 utf8mb4 字符集可以存儲表情符號。
Output
mysql> SELECT * FROM users;
+----+-----------+----------------------+
| id | name | email |
+----+-----------+----------------------+
| 1 | Arun Jith | [email protected] |
| 2 | Jane Doe | [email protected] |
| 3 | 𝌆 | [email protected] |
+----+----------+-----------------------+
3 rows in set (0.00 sec)
此查詢將從用戶表中選擇所有行。查詢的輸出將是用戶表中所有行的列表,包括每個用戶的 ID
、name
、email
。表情符號將被存儲爲表情符號,因爲 utf8mb4 字符集可以存儲表情符號。
總結
如您所見,utf8mb4 字符集可以存儲完整 Unicode 字符集中的所有字符,包括表情符號和其他補充字符。這使得它成爲存儲複雜文本數據、文本搜索和比較的不錯選擇。另一方面,utf8 字符集只能存儲 BMP 中的字符。這意味着它無法存儲表情符號或其他補充字符。
一般來說,建議所有新應用程序都使用 utf8mb4。這將確保您的數據可以正確存儲和處理,無論它包含什麼字符。
更多技術文章,請訪問:https://opensource.actionsky.com/
關於 SQLE
SQLE 是一款全方位的 SQL 質量管理平臺,覆蓋開發至生產環境的 SQL 審覈和管理。支持主流的開源、商業、國產數據庫,爲開發和運維提供流程自動化能力,提升上線效率,提高數據質量。