在将5.6数据库更新到8之后,我得到了不同的行为。
在5.6中,如果运行以下语句,将得到零行,这正是我希望得到的:
SELECT * FROM EntityCustomerContact where CustomerContactID <> TRIM(CustomerContactID);在8.0中,我将返回数百行。CustomerContactID是varchar(32);
我的理解是,MySQL中的所有CHAR、VARCHAR和TEXT值都是比较的,而不考虑任何尾随空格。
更新过程包括将mysqldump从5.6导入到8.0。除了移到8.0之外,我唯一改变的是更新从utf8mb4_unicode_ci到utf8mb4_0900_ai_ci的所有表和列的排序规则。这是我第一次升级到utf8mb4_0900_ai_ci排序规则。
我执行了从5.6/7到8.0的许多其他升级,但从未遇到过这个问题--我在其他8.0 (特别是8.0.29)数据库上运行了测试查询,这些数据库都以相同的方式进行了升级,但排序更改除外,并且收到了预期的结果。
我已经搜索了可能的mysqld设置来解决这个问题,但是还不够。
发布于 2022-05-26 07:22:46
MySQL排序规则有pad属性,它的值为PAD空间或没有PAD。
对于非二进制字符串(CHAR、VARCHAR和TEXT值),字符串排序器pad属性在字符串末尾的尾随空格比较中确定处理。没有衬垫排序规则在比较中将尾随空格视为重要,就像任何其他字符一样。衬垫空间排序规则在比较中将尾随空格视为无关紧要;字符串被比较时不考虑尾随空格https://dev.mysql.com/doc/refman/8.0/en/char.html。
您已经将utf8mb4_unicode_ci更改为utf8mb4_0900_ai_ci,下面的查询返回PAD_ATTRIBUTE差异:
mysql> SELECT COLLATION_NAME,
PAD_ATTRIBUTE
FROM INFORMATION_SCHEMA.COLLATIONS
WHERE CHARACTER_SET_NAME = 'utf8mb4'
AND COLLATION_NAME in ('utf8mb4_unicode_ci','utf8mb4_0900_as_ci');
+--------------------+---------------+
| COLLATION_NAME | PAD_ATTRIBUTE |
+--------------------+---------------+
| utf8mb4_0900_as_ci | NO PAD |
| utf8mb4_unicode_ci | PAD SPACE |
+--------------------+---------------+发布于 2022-05-26 03:30:51
我一直在想这个。也许这解释了这一点(来自8.0.1的changelog ):
- 2017-04-10 8.0.1发展里程碑-字符集支持- Unicode 9.0.0排序规则的PAD属性从pad空间更改为无PAD。因此,这些排序规则现在处理字符串末尾的空格,就像处理其他字符一样。受影响的排序规则具有包含字符串0900的名称。对具有9.0.0排序规则的VARCHAR列的比较,在尾部空格方面与其他排序规则不同。例如,“a”和“a”作为不同的字符串进行比较,而不是同一字符串。例如: mysql>设置名称'latin1‘COLLATE’latin1 1_瑞典_ci‘;
mysql> SELECT 'a' = 'a ';
+------------+
| 'a' = 'a ' |
+------------+
| 1 |
+------------+
mysql> SET NAMES 'utf8mb4' COLLATE 'utf8mb4_0900_ai_ci';
mysql> SELECT 'a' = 'a ';
+------------+
| 'a' = 'a ' |
+------------+
| 0 |
+------------+INFORMATION_SCHEMA 校勘表现在有一个PAD_ATTRIBUTE列,该列指示每个排序规则的pad属性。latin1_de排序规则中涉及早期权重字符串截断的问题已经得到纠正。唯一可能的效果是重量_字符串()函数的结果。
我认为底线是避免使用CHAR;坚持使用VARCHAR。我不认为COLLATION与这个问题有多大关系,而是“填充”。
https://dba.stackexchange.com/questions/312585
复制相似问题