我有一个在列上定义排序规则的表:
CREATE TEMPORARY TABLE test_table (
utf8_col VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_bin
);
INSERT INTO test_table VALUES('ã');
根据 MySQL可强制性规则,当将该列的值与文字进行比较时:
SELECT utf8_col < _utf8mb4'ñ' FROM test_table;
- column collation coercibility 值为 2;
- 文字CCV是4
这应该会导致比较失败,因为列 CCV 具有更高的优先级,并且应该使用utf8_bin
不能处理utf8mb4
字符集的排序规则。
然而,比较是成功的。这是为什么?
因为 MySQL 很好,可以自动更正用户错误,但这只是因为它可以。
你没有错:
和:
但是,您没有看到您认为在测试中看到的内容,因为您没有使用需要“utf8”归类的“mb4”版本的数据进行测试。您正在使用适合非补充字符的
utf8
字符集的“安全”值进行测试。在这种情况下,MySQL 只是简单地使用列的字符集utf8
—— 并且utf8_bin
排序规则就好了。当您使用 4 字节字符(即增补字符)时,世界看起来有点不同。在这种情况下,字符不能存在于
utf8
字符集中(因为utf8
字符集只能处理 BMP 字符/前 65,536 个代码点/U+0000 到 U+FFFF/每个字符为 1 到 3 个字节)。因此,由于无法将字符串文字的字符集更改为适用于列排序规则的字符集utf8_bin
——您会收到一条错误消息:我使用代码点 U+1F369(即甜甜圈表情符号:“?”)进行了测试:
在 dbfiddle.uk 上查看上面的示例代码
第一个结果集
SELECT
是:这表明
utf8mb4
字符串被强制转换为utf8
,并且大家都很高兴。很高兴,直到甜甜圈先生出现在第二个SELECT
声明中(你会认为甜甜圈会让一切变得更好,不是吗?我通常会这样做?)。