tidb字符集-排序规则

tidb3.0不支持大小写区分的utf8_general_cs排序规则吗? 在创建databse时报错:

CREATE DATABASE test1 character set utf8 COLLATE utf8_general_cs; unknown collation:‘utf8_general_cs’

稍等,我们测试下

您好: 是的,不支持

好的,谢谢,目前对于精确查询(区分大小写),推荐的排序规则是什么?

用utf8_bin是不是同样数据占用存储会增多?

用utf8_bin是不是同样数据占用存储会增多?

Hi,请注意通常而言,存储的占用只与字符集相关,与排序规则是无关的,因此可以认为 utf8_general_cs 与 utf8_bin 是一样的,因为他们都属于 utf8 字符集。

然而,以上的说法只适用于 MySQL;对于 TiDB 而言,由于底层的存储 layout 是 Key-Value(TiKV),出于性能考虑,索引编码是 mem-comparable bytes,因此在 索引 的存储上,占用的空间是与排序规则相关的。

再然而(- -),在 TiDB 4.0 之前,TiDB 实际上仅支持一种排序规则(utf8_bin),其他被允许制定的排序规则,例如 utf8_general_ci、utf8_unicode_ci…都可以写,但全部当作 utf8_bin 处理。

在 TiDB 4.0 之后,我们支持了 CI Collation 以满足一些用户对于大小写不敏感排序规则需求,具体请见文档:https://pingcap.com/docs-cn/dev/reference/sql/characterset-and-collation/

简单总结一下:

  • 如果您对于大小写不敏感的排序规则有强需求,可以打开 TiDB 4.0 的 CI Collation 选项,使用 utf8_general_ci collation
  • 如果没有上述需求,请直接使用 utf8_bin,这也是除 TiDB 4.0 CI Collation 之外,唯一支持的排序规则。
2赞

好的,非常感谢

:muscle:

±---------------------------±-----------------------+
| DEFAULT_CHARACTER_SET_NAME | DEFAULT_COLLATION_NAME |
±---------------------------±-----------------------+
| utf8mb4 | utf8mb4_bin |
±---------------------------±-----------------------+

TIDB 4.0可以更改系统级别默认的排序规则吗,比如将utf8mb4_bin 更改为 ```
utf8mb4_general_ci;

在 4.0 版本,从语义上支持了 CI 排序规则,并新增了配置开关 new_collations_enabled_on_first_bootstrap仅在新集群初次初始化时决定是否启用新排序规则框架。如果是已有集群,暂时不支持在线修改。详情如下:

在 4.0 版本,从语义上支持了 CI 排序规则 ;;
你的意思是4.0后的版本,排序是默认CI排序的吗

默认不是的,需要设置,具体见上面的文档说明~

上面文章我看了 初始化后也启用了 但是从mysql同步过来的排序还是 ```
utf8mb4_bin

请问您在 MySQL 的表 SHOW CREATE TALBE 的结果,Collation 是否是 utf8mb4_bin?

mysql是ci排序,我把tidb的这些参数设置设置成ci还是不行,是我设置的不对吗?只有mysql建表时指定ci,同步过来才时ci。

show global variables like ‘%collation%’;
±---------------------±-------------------+
| Variable_name | Value |
±---------------------±-------------------+
| collation_connection | utf8mb4_general_ci |
| collation_database | utf8mb4_general_ci |
| collation_server | utf8mb4_general_ci |
±---------------------±-------------------+
3 rows in set (0.04 sec)

1、在mysql这样见表同步到tidb是ci,CREATE TABLE zz ( a varchar(20) NOT NULL, PRIMARY KEY (a) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

2、在mysql这样见表同步到tidb就是bin,但是我mysql那边显示这个字段时ci,CREATE TABLE zz ( a varchar(20) NOT NULL, PRIMARY KEY (a) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ;

3、tidb能不能设置下,让排序默认是ci,而不是bin;即使按2那样的建表语句同步过来也是ci排序;

请问您是使用什么工具进行同步的?这里需要看一下,同步到 TiDB 的建表语句是怎样的。您可以看一下,使用两种不同写法时候,MySQL 的 SHOW CREATE TABLE 结果是否有差异(是否显式制定了 COLLATE)。

简单说来,TiDB/MySQL 的排序规则是这样的决定的:

  • 如果建表语句是 CREATE TABLE … CHARSET chs COLLATE coll,那么按照对应的 chs 和 coll 建表。
  • 如果建表语句是 CREATE TABLE … CHARSET chs,那么使用 chs 的默认排序规则建表,注意 TiDB 中 utf8mb4 的默认排序规则(utfmb4_bin)与 MySQL 不同。
  • 如果建表语句是 CREATE TABLE …,那么使用的是 DATABASE 的默认字符集和排序规则。

1、我用的dm同步的,在mysql中显示指定了显式制定了 COLLATE用ci排序,同步到tidb也是ci排序,如果不显示指定ci排序,同步到tidb就是默认utf8mb4_bin(因为tidb默认是utf8mb4_bin),这我通过看官方文档和实验明白;
2、看来tidb现在还不支持把默认utf8mb4_bin排序,通过参数设置成utf8mb4_general_ci排序;
3、非常感谢您的恢复和解答,谢谢!

看来tidb现在还不支持把默认utf8mb4_bin排序,通过参数设置成utf8mb4_general_ci排序;

是的,如果建表语句显式指定了 utf8mb4_bin,TiDB 不会替换成 utf8mb4_general_ci。

如果有后续问题,欢迎继续讨论!