0
点赞
收藏
分享

微信扫一扫

困扰我的排序问题,竟然是这样

Java旺 2022-08-01 阅读 75


🍺 碰到它了

验证一个页面列表的排序功能,我的UI脚本代码是用python实现的,用python排序的结果,和页面点击排序出来的结果不一样

首先想到的是这可让我逮到功能bug了,为了和开发阐述这个问题,更加有理有据,我去数据库亲自去查探一番来证明这个排序接口调用有问题,我满怀信心的去数据库操作了一番,结果打脸了

数据库里操作结果和页面操作排序的结果是一样的, 我不禁怀疑难道python的排序和数据库的排序有啥不一样么,不是都按照ASCII的编码的大小来排的么(我要排序的内容都是字符串),这一查不知道,感觉像走进了新世界的大门

🎈 查探之旅

我首先去搜索了数据库的排序原理和python sort函数的排序原理

⭐数据库mysql的排序规则

因为不是对数据库很熟悉,平常用它最多修改个字段和查询一番,原来它还有这么多曲曲绕绕

mysql排序是根据它设定的字符集的,不同的字符集,它的排序不一样,可以通过以下语句来查看你当前数据库使用的是什么字符集

(1)😸查看数据库的排序规则 SHOW VARIABLES LIKE 'collation%';

SHOW VARIABLES LIKE 'collation%';

结果:

困扰我的排序问题,竟然是这样_特殊字符

(2)😸 查看数据库的编码格式show variables like 'char%';

show variables like 'char%';

结果:

困扰我的排序问题,竟然是这样_Python_02

(3)😸查看字段编码和排序规则 show full columns from table_name;

show full columns from

结果: 涉及到隐私,私密地方就打了码

困扰我的排序问题,竟然是这样_python_03

(4)😸查看字段编码和排序规则的另一种方式 show create table 这个示例信息太多了,只截取其中一个字段,可以看到collate关键字后面跟的字符集

`status` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT ''IN_PROGRESS'' COMMENT ''IN_PROGRESS, COMPLETED'',
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci'

⭐ 各种规则的区别

从以上的查询结果,依据我想要排序的字段,主要讨论以下三种排序规则,根据好多资料,基本都是这样描述的

  • 😸 utf8mb4_general_ci:不区分大小写,校对速度快,但准确度稍差
  • 😸 utf8mb4_unicode_ci:不区分大小写,准确度高,但校对速度稍慢
  • 😸 utf8mb4_bin:字符串每个字符串用二进制数据编译存储。 区分大小写,而且可以存二进制的内容

我要排序的字段使用的排序规则是utf8mb4_unicode_ci, 这个不区分大小写,python是什么样的呢?

⭐探寻python排序

我去看了python sort的源码,大家有兴趣可以看 ​​github.com/python/cpyt…​​

我找到了我认为的关键之处,python这个sort排序规则应该是按二进制

困扰我的排序问题,竟然是这样_数据库_04

从这里看,感觉问题是可以解决了,鉴于数据库因为一些安全啥的,个人是没有权限更改字符规则,就是更改为utf8mb4_bin, 那么我把python排序更改为大小写不敏感就好了

content.sort(key=str.lower, reverse=reverse_tag)

但是这仍然没有解觉我的问题,我的问题出在特殊字符上

⭐特殊字符之战

我验证的这个字段是允许特殊字符输入的,那么无论是特殊字符还是其他,我想应该都有一个统一的编码值,排序比较这个编码值大小来排吧

我先找mysql的这个 ​​utf8mb4_unicode_ci编码集​​,先截一部分

困扰我的排序问题,竟然是这样_特殊字符_05

密密麻麻的真不好看,我搜我想要的下划线和减号编码,竟然没搜到

让我们再看下ASCII的编码,待会实验会用到

困扰我的排序问题,竟然是这样_数据库_06

😸 实践

(1)😸我先用python的sort函数来排序这些特殊字符

困扰我的排序问题,竟然是这样_特殊字符_07

从结果也可看出,和预期是一样的,是按照编码值大小来排

(2)😸 那么mysql是怎么样的呢

**朋友们,我惊呆了,原谅我的无知,这很魔幻啊

下划线和减号它们遥遥领先啊,叹号在第四位,不是预想的第一**

困扰我的排序问题,竟然是这样_MySQL_08

事已至此,我放弃挣扎,我是真的不懂这些特殊字符到底在数据库里是怎么存储编码的,谁是数据库大神可以来救救我

🍺 后记

目前我有两条路可走 (1)在数据库实践,摸索出特殊字符的排序规律,然后在脚本里自己写个排序算法,不用python自带的 (2)建数据测试排序,压根不输这些特殊字符

举报

相关推荐

0 条评论