MySQL8.0 比较大小的逻辑问题

MySQL8.0 比较大小的问题

在collate为utf8mb4_0900_as_cs下,select STRCMP('a', 'A'); 为 -1,也就是 a比A小,与python不同。但是ord('a'), ord('A'); 为 97 和65,明明a比A要大,难道是没有根据unicode码的大小比较?而且理论上来说,如果a比A小,那么 select STRCMP('a1', 'A');应该也是-1,因为第一位比较出大小后不会再看后面的位置了,但是mysql执行的结果却是1。但是select strcmp('11', '2');结果又是-1也就是‘11’比‘2’小。实在找不出他的逻辑是什么,完全颠覆python的比较大小的逻辑,百思不得其解,请大家赐教。

对,你的理解是对的

【以下回答由 GPT 生成】

问题的解答如下:

MySQL在比较大小时,确实是根据字符集中字符的排序顺序进行比较。utf8mb4_0900_as_cs字符集按照Unicode码的大小来排序,因此会导致一些看似逻辑不符的结果。

首先,对于STRCMP('a', 'A')的结果为-1,这是因为在utf8mb4_0900_as_cs字符集中,小写字母'a'的Unicode码(U+0061)比大写字母'A'(U+0041)大,所以结果为-1。

SELECT STRCMP('a1', 'A')这个例子中,MySQL的比较是逐个字符比较的。所以,它会先比较'a'和'A',由于'a'比'A'大,所以对于整个字符的比较结果为1。

对于SELECT STRCMP('11', '2'),MySQL同样是逐个字符比较的,它会先比较'1'和'2',由于'1'比'2'小,所以整个字符的比较结果为-1。

总结来说,MySQL在比较大小时,根据字符集的排序顺序进行比较,而不是按照字符的Unicode码大小进行比较。所以,在utf8mb4_0900_as_cs字符集下,有些比较结果可能与我们的直觉不符。

如果你希望在MySQL中按照Unicode码大小进行比较,可以使用COLLATE utf8mb4_unicode_ci来设置字符集。具体可以如下使用:

SELECT STRCMP('a', 'A' COLLATE utf8mb4_unicode_ci);
SELECT STRCMP('a1', 'A' COLLATE utf8mb4_unicode_ci);
SELECT STRCMP('11', '2' COLLATE utf8mb4_unicode_ci);

这样的话,就能按照Unicode码大小进行比较了。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^