【问题标题】:How come this character sequence comparison returns true?这个字符序列比较怎么会返回true?
【发布时间】:2017-09-08 05:26:34
【问题描述】:

下面的SQL语句怎么会在MySQL中返回true?

SELECT 'SeP' = 'sęp';

mysql> select 'SeP' = 'sęp';
+----------------+
| 'SeP' = 'sęp'  |
+----------------+
|              1 |
+----------------+
1 row in set (0.00 sec)

我的数据库的字符集和排序规则如下。

mysql> select @@character_set_database, @@collation_database, @@collation_connection;
+--------------------------+----------------------+------------------------+
| @@character_set_database | @@collation_database | @@collation_connection |
+--------------------------+----------------------+------------------------+
| utf8mb4                  | utf8mb4_general_ci   | utf8_general_ci        |
+--------------------------+----------------------+------------------------+
1 row in set (0.00 sec)

【问题讨论】:

  • 我们必须查看规范,但我认为这两个字符在一般排序规则中被认为是相等的,而不是绑定到任何特定语言是合理的。
  • 您可以尝试使用CASE WHEN 来实现此功能。
  • @SagarGangwal 你可以试试,但是用处不大
  • @Jagger 您应该查看SELECT @@collation_connection;,因为您的查询不使用数据库...您的查询将使用 DUAL 表
  • @RaymondNijland 我刚刚在我的问题中添加了@@collation_connection。

标签: mysql collation mysql-5.7


【解决方案1】:

您有一个不区分大小写的(ci 在排序规则名称的末尾表示这一点)和通用排序规则,因此 MySQL 以不区分大小写且通常不区分重音的方式比较 2 个字符串,因此这两个字符串是相同的.

Case sensitivity in string searches 上的 MySQL 手册说:

对于非二进制字符串(CHAR、VARCHAR、TEXT),字符串搜索使用比较操作数的排序规则。对于二进制字符串(BINARY、VARBINARY、BLOB),比较使用操作数中字节的数值;这意味着对于字母字符,比较将区分大小写。

处理非二进制字符串和二进制字符串之间的比较 作为二进制字符串的比较。

简单的比较操作(>=、>、=、

要强制区分大小写,请使用区分大小写 (_cs) 或二进制排序规则 (_bin)。要强制区分重音,您需要使用特定于语言的排序规则(在您的情况下为 utf8mb4_polish_xxx)或二进制排序规则。通用排序规则很少区分重音字符和非重音字符。

【讨论】:

  • 可能不是直接可见,但是那里有一个特殊的波兰字符ę。
  • @Jagger - 它是可见的,但影子是正确的。您使用的排序规则为您的波兰重音字符和拉丁字母 e 增加了相同的权重。
  • @Jagger 如果你使用 SET SESSION collation_connection = 'utf8_bin'; 然后 SELECT 'SeP' = 'sęp'; 你的结果是 0... utf8_bin 是最好的 utf8 排序规则,这是我的意见。
  • @Jagger 这个问题应该在一个新问题中,而不是在这个问题中,这会让未来的读者感到困惑
  • @Jagger 你可以在 my.ini 中设置任何服务器变量的默认值
【解决方案2】:

COLLATION utf8mb4_polish_ci 会将这些视为“单独的字母”:ą ć ę ń ś ź ż

例如,a ą b。在大多数其他排序规则中,a = ą b。

mysql> SET NAMES utf8mb4 COLLATE utf8mb4_polish_ci;

mysql> SELECT 'SeP' = 'sęp';
+----------------+
| 'SeP' = 'sęp'  |
+----------------+
|              0 |
+----------------+

请参阅this,详细了解各种排序规则有何不同。

【讨论】:

  • 我错过了什么吗?或者说错了什么?为什么投反对票?
猜你喜欢
  • 2020-07-30
  • 2012-04-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-24
  • 2014-04-17
  • 2015-06-13
相关资源
最近更新 更多