代码改变世界

MySQL8.0中utf8mb4的强大:释放多语言数据的全部潜能

2023-07-15 14:05  abce  阅读(544)  评论(0编辑  收藏  举报

 

在现代网络应用中,支持多种语言和字符集变得越来越重要。随着全球化的兴起,存储和处理多语言数据的需求已变得至关重要。MySQL作为最流行的关系数据库管理系统之一,它意识到了这一需求,并在其8.0版本中引入了utf8mb4,从而改变了游戏规则。在本文中,我们将通过实际示例探讨utf8mb4及其在MySQL 8.0中的优势。

理解utf8mb4
在深入了解utf8mb4的优势之前,让我们先弄清楚utf8mb4代表什么。在MySQL中,"utf8"指的是支持Unicode字符集的字符编码,每个字符最多使用三个字节。另一方面,utf8mb4是utf8的一个修改版本,它支持完整的Unicode字符集,包括表情符号和其他补充字符,每个字符最多使用4个字节。

MySQL中最初的utf8实现只支持基本多语言(Basic Multilingual Plane, BMP)的字符,这大约占所有Unicode字符的90%。utf8mb4支持整个Unicode字符集,包括表情符号和其他补充字符。它通过每个字符最多使用四个字节而不是utf8使用的三个字节来实现这一点。

下面的表格显示了utf8和utf8mb4之间的区别:

历史上,MySQL使用字符集utf8作为utf8mb3的别名。然而,从MySQL 8.0.28开始,utf8mb3仅在SHOW语句的输出和Information Schema表中引用该字符集时使用。将来,utf8有望成为对utf8mb4的引用。为避免任何歧义,建议在引用该字符集时明确指定utf8mb4。

可以知道,utf8、utf8mb3和utf8mb4之间的主要区别在于每个字符的最大字节数。utf8和utf8mb3只能存储基本多语言(BMP)中的字符,而utf8mb4还可以存储Supplementary Plane中的字符。这意味着utf8mb4可以支持更多字符,包括表情符号、数学符号和其他特殊字符。

utf8是MySQL 5.7及更早版本的默认字符集,而utf8mb3是MySQL 8.0的默认字符集。但是,在MySQL 8.0.28及更高版本中,utf8mb4是默认字符集。

最后,utf8和utf8mb3在MySQL 8.0中被弃用。这意味着它们最终将从MySQL中移除,因此建议使用utf8mb4代替。

因此,如果需要存储所有Unicode字符,包括表情符号和其他补充字符,那么应该使用utf8mb4。但是,如果只需要存储BMP中的字符,那么utf8可能就足够了。

下面是使用MySQL表和查询比较utf8和utf8mb4的示例:

MySQL 5.7

mysql> select version();
+------------+
| version()  |
+------------+
| 5.7.23-log |
+------------+

CREATE TABLE abce (
  id INT AUTO_INCREMENT PRIMARY KEY,
  name VARCHAR(255) CHARACTER SET utf8,
  email VARCHAR(255) CHARACTER SET utf8
);
mysql> show create table abce\G
*************************** 1. row ***************************
       Table: abce
Create Table: CREATE TABLE `abce` (
  `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=utf8 COLLATE=utf8_bin
1 row in set (0.00 sec)

mysql> 

插入三行记录,包含emoji:

mysql> INSERT INTO abce (name, email) VALUES
    -> ('Arun Jith', 'arunjith@example.com'),
    -> ('Jane Doe', 'janedoe@example.com'),
    -> ('𝌆', 'emoji@example.com');
ERROR 1366 (HY000): Incorrect string value: '\xF0\x9D\x8C\x86' for column 'name' at row 3

遇到的错误:"ERROR 1366 (HY000): Inorrect string value: 'xF0x9Dx8Cx86' for column 'name' at row 3," 提示'abce'表中'name'列使用的字符编码有问题。当尝试在 "name"列中插入Unicode字符"𝌆"时发生了错误。

mysql> INSERT INTO abce (name, email) VALUES
    -> ('Arun Jith', 'arunjith@example.com'),
    -> ('Jane Doe', 'janedoe@example.com');
Query OK, 2 rows affected (0.01 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> 

MySQL 8.0

>select version();
+-----------+
| version() |
+-----------+
| 8.0.30    |
+-----------+

>CREATE TABLE abce (
    ->   id INT AUTO_INCREMENT PRIMARY KEY,
    ->   name VARCHAR(255) CHARACTER SET utf8,
    ->   email VARCHAR(255) CHARACTER SET utf8
    -> );
Query OK, 0 rows affected, 2 warnings (0.01 sec)
> show create table abce\G
*************************** 1. row ***************************
       Table: abce
Create Table: CREATE TABLE `abce` (
  `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)

该表的姓名和电子邮件列均使用utf8mb3字符集。这意味着该表可以存储BMP中的所有字符,但不能存储表情符号或其他补充字符。

查询

INSERT INTO abce (name, email) VALUES
('Arun Jith', 'arunjith@example.com'),
('Jane Doe', 'janedoe@example.com'),
('𝌆', 'emoji@example.com');

与前面的示例一样,遇到的错误消息:"ERROR 1366 (HY000): Inorrect string value: 'xF0x9Dx8Cx86' for column 'name' at row 3,"(不正确的字符串值:第3行'name'列的'xF0x9Dx8Cx86')表明'abce'表中'name'列使用的字符编码有问题。当尝试在 "name"列中插入Unicode字符"𝌆"时发生了错误。

>INSERT INTO abce (name, email) VALUES
    -> ('Arun Jith', 'arunjith@example.com'),
    -> ('Jane Doe', 'janedoe@example.com'),
    -> ('𝌆', 'emoji@example.com');
ERROR 1366 (HY000): Incorrect string value: '\xF0\x9D\x8C\x86' for column 'name' at row 3
>INSERT INTO abce (name, email) VALUES
    -> ('Arun Jith', 'arunjith@example.com'),
    -> ('Jane Doe', 'janedoe@example.com');
Query OK, 2 rows affected (0.00 sec)

为了确保表情符号的正确存储,让我们使用utf8mb4字符集创建表列。之后,我们可以继续检查表情符号插入是否正常。

>CREATE TABLE abce (
    ->   id INT AUTO_INCREMENT PRIMARY KEY,
    ->   name VARCHAR(255) CHARACTER SET utf8mb4,
    ->   email VARCHAR(255) CHARACTER SET utf8mb4
    -> );
Query OK, 0 rows affected (0.02 sec)
>show create table abce\G
*************************** 1. row ***************************
       Table: abce
Create Table: CREATE TABLE `abce` (
  `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)
>INSERT INTO abce (name, email) VALUES
    -> ('Arun Jith', 'arunjith@example.com'),
    -> ('Jane Doe', 'janedoe@example.com'),
    -> ('𝌆', 'emoji@example.com');
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0

 

一般来说,建议所有新应用程序使用utf8mb4。这将确保数据能够正确存储和处理,无论其中包含哪些字符。