【问题标题】:MySQL collate clause - before or after the like clause?MySQL collat​​e 子句 - 在like 子句之前还是之后?
【发布时间】:2021-02-15 15:47:41
【问题描述】:

我正在努力将我们的数据库从 utf8 (utf8mb3) 迁移到 utf8mb4(为最终迁移到 MySQL 8 做准备),由于系统的性质以及数据库和主机的数量,我做不到一口气。所以,我想弄清楚在应用程序正常工作之前是否先迁移数据库(一次一个)。

在尝试时,我遇到了以下情况,想就推荐的方法和原因获得专家意见。

MySQL 信息:

  • 版本 - 5.7.30-33
  • innodb_version - 5.7.30-33
  • version_comment - Percona Server (GPL),第 33 版,修订版 6517692
  • character_set_client - utf8
  • character_set_connection - utf8
  • character_set_database - utf8mb4
  • collat​​ion_connection - utf8_general_ci
  • collat​​ion_database - utf8mb4_general_ci

我有一张桌子(显示创建表格

CREATE TABLE `mb4table1` (
  `name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
  `age` int(11) DEFAULT NULL,
  PRIMARY KEY (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4

有价值观

mysql> select * from mb4table1;
+------+------+
| name | age  |
+------+------+
| abc  |   43 |
| one  |   41 |
| two  |   42 |
+------+------+
3 rows in set (0.00 sec)

有了这张表和数据, (1) 如果我执行查询

mysql> select * from mb4table1 where name like 'Abc';
Empty set (0.00 sec)

当然,它没有找到任何记录。 (2) 如果我这样做

mysql> select * from mb4table1 where name like 'Abc' collate utf8_general_ci;
+------+------+
| name | age  |
+------+------+
| abc  |   43 |
+------+------+
1 row in set (0.00 sec)

它能够找到abc的记录。 (3) 而如果我移动 collat​​e 子句,

mysql> select * from mb4table1 where name collate utf8_general_ci like 'Abc';
ERROR 1253 (42000): COLLATION 'utf8_general_ci' is not valid for CHARACTER SET 'utf8mb4'

(4) 而且,如果我使用 utf8mb4 排序规则,那么它可以正常工作

mysql> select * from mb4table1 where name collate utf8mb4_general_ci like 'Abc';
+------+------+
| name | age  |
+------+------+
| abc  |   43 |
+------+------+
1 row in set (0.00 sec)

我的问题是,(2)(3) 有什么区别?查询 (2) 显然应用了 collat​​e 子句并返回了预期结果。而且,如果我必须使用 (3),我该如何让它发挥作用?

注意:列排序规则必须保留。 10 个查询中只有几个查询可能需要使用 collat​​e 子句来执行不区分大小写的搜索。

【问题讨论】:

  • 'abc' 是一个不恰当的例子——它在几乎所有字符集和排序规则中都以相同的方式进行编码和比较。
  • 在什么时候更改与 connections 关联的字符集和排序规则?这就是控制文字 'Abc'
  • @RickJames 建立连接时设置连接排序规则(JDBC connectionCollat​​ion=utf8_general_ci)
  • 要逐步加入,请记住这一点...连接参数说明客户端中的编码。列定义说明表中的编码。 这些不必相同。INSERTSELECT(等)将转换(如果可能)客户端和数据库之间的文本流动
  • 而且...我不清楚literals(例如,'abc')何时需要转换。可以做的另一件事:_utf8mb4'abc' 是一种限定文字以具有特定编码的方法。

标签: mysql sql-like collation


【解决方案1】:

只要 mysql 不支持它,我认为无论如何都不可能

你可以检查

SHOW COLLATION WHERE Charset = 'utf8mb4';

支持哪些排序规则

https://dev.mysql.com/doc/refman/8.0/en/charset-mysql.html,您可以看到所有开头都有utf8mb4_

如果你想更深入。你可以从https://dev.mysql.com/doc/refman/8.0/en/charset-charsets.html开始

 'Abc' collate utf8_general_ci    

utf8_general_ci 属于字符串“Abc”,它没有 uf8mb4(4 字节)字符,可以保存地转换为该分类。

name collate utf8_general_ci

utf8_general_ci 属于 uf8mb4 (4byte) 的列名,并且不能转换为该排序规则,因为它不受支持(见上文)

【讨论】:

  • 谢谢。我明白那个。但我的问题是为什么相同的基于 utf8 的排序规则 (utf8_general_ci) 在 (2) 中可以正常工作,但在 (3) 中却不行。
  • 知道了。感谢您的信息
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-12
  • 2014-08-16
  • 1970-01-01
相关资源
最近更新 更多