From 3da508ef79afa10588702e341b2ac0ead21cc5de Mon Sep 17 00:00:00 2001 From: ireneontheway <48651140+ireneontheway@users.noreply.github.com> Date: Mon, 10 Aug 2020 11:20:06 +0800 Subject: [PATCH] cherry pick #4193 to release-4.0 Signed-off-by: ti-srebot --- character-set-and-collation.md | 88 +++++++++++++++++++++++++++++++++- 1 file changed, 86 insertions(+), 2 deletions(-) diff --git a/character-set-and-collation.md b/character-set-and-collation.md index 8388cdc14c34..9dbb01722fe4 100644 --- a/character-set-and-collation.md +++ b/character-set-and-collation.md @@ -9,9 +9,41 @@ aliases: ['/docs-cn/stable/character-set-and-collation/','/docs-cn/v4.0/characte ## 字符集和排序规则的概念 -字符集 (character set) 是符号与编码的集合。 +字符集 (character set) 是符号与编码的集合。TiDB 中的默认字符集是 utf8mb4,与 MySQL 8.0 及更高版本中的默认字符集匹配。 -排序规则 (collation) 是在字符集中比较字符的规则。 +排序规则 (collation) 是在字符集中比较字符以及字符排序顺序的规则。例如,在二进制排序规则中,比较“A”和“a”的结果是不一样的: + +{{< copyable "sql" >}} + +```sql +SET NAMES utf8mb4 COLLATE utf8mb4_bin; +SELECT 'A' = 'a'; +SET NAMES utf8mb4 COLLATE utf8mb4_general_ci; +SELECT 'A' = 'a'; +``` + +```sql +mysql> SELECT 'A' = 'a'; ++-----------+ +| 'A' = 'a' | ++-----------+ +| 0 | ++-----------+ +1 row in set (0.00 sec) + +mysql> SET NAMES utf8mb4 COLLATE utf8mb4_general_ci; +Query OK, 0 rows affected (0.00 sec) + +mysql> SELECT 'A' = 'a'; ++-----------+ +| 'A' = 'a' | ++-----------+ +| 1 | ++-----------+ +1 row in set (0.00 sec) +``` + +TiDB 默认使用二进制排序规则。这一点与 MySQL 不同,MySQL 默认使用不区分大小写的排序规则。 ## 支持的字符集和排序规则 @@ -52,6 +84,22 @@ mysql> show collation; 5 rows in set (0.01 sec) ``` +TiDB 支持以下排序规则: + +```sql +mysql> show collation; ++-------------+---------+------+---------+----------+---------+ +| Collation | Charset | Id | Default | Compiled | Sortlen | ++-------------+---------+------+---------+----------+---------+ +| utf8mb4_bin | utf8mb4 | 46 | Yes | Yes | 1 | +| latin1_bin | latin1 | 47 | Yes | Yes | 1 | +| binary | binary | 63 | Yes | Yes | 1 | +| ascii_bin | ascii | 65 | Yes | Yes | 1 | +| utf8_bin | utf8 | 83 | Yes | Yes | 1 | ++-------------+---------+------+---------+----------+---------+ +5 rows in set (0.01 sec) +``` + > **注意:** > > TiDB 中的默认排序规则(后缀为 `_bin` 的二进制排序规则)与 [MySQL 中的默认排序规则](https://dev.mysql.com/doc/refman/8.0/en/charset-charsets.html)不同,后者通常是一般排序规则,后缀为 `_general_ci`。当用户指定了显式字符集,但依赖于待选的隐式默认排序规则时,这个差异可能导致兼容性问题。 @@ -74,6 +122,42 @@ SHOW COLLATION WHERE Charset = 'utf8mb4'; 2 rows in set (0.00 sec) ``` +## TiDB 中的 `utf8` 和 `ut8mb4` + +MySQL 限制字符集 `utf8` 为最多 3 个字节。这足以存储在基本多语言平面 (BMP) 中的字符,但不足以存储表情符号等字符。因此,建议改用字符集`utf8mb4`。 + +默认情况下,TiDB 同样限制字符集 `utf8` 为最多 3 个字节,以确保 TiDB 中创建的数据可以在 MySQL 中顺利恢复。你可以禁用此功能,方法是在 TiDB 配置文件中将 `check-mb4-value-in-utf8` 的值更改为 `FALSE`。 + +以下示例演示了在表中插入 4 字节的表情符号字符时的默认行为。`utf8` 字符集下 `INSERT` 语句不能执行,`ut8mb4` 字符集下可以执行 `INSERT` 语句: + +```sql +mysql> CREATE TABLE utf8_test ( + -> c char(1) NOT NULL + -> ) CHARACTER SET utf8; +Query OK, 0 rows affected (0.09 sec) + +mysql> CREATE TABLE utf8m4_test ( + -> c char(1) NOT NULL + -> ) CHARACTER SET utf8mb4; +Query OK, 0 rows affected (0.09 sec) + +mysql> INSERT INTO utf8_test VALUES ('😉'); +ERROR 1366 (HY000): incorrect utf8 value f09f9889(😉) for column c +mysql> INSERT INTO utf8m4_test VALUES ('😉'); +Query OK, 1 row affected (0.02 sec) + +mysql> SELECT char_length(c), length(c), c FROM utf8_test; +Empty set (0.01 sec) + +mysql> SELECT char_length(c), length(c), c FROM utf8m4_test; ++----------------+-----------+------+ +| char_length(c) | length(c) | c | ++----------------+-----------+------+ +| 1 | 4 | 😉 | ++----------------+-----------+------+ +1 row in set (0.00 sec) +``` + ## 不同范围的字符集和排序规则 字符集和排序规则可以在设置在不同的层次。