utf8mb4_cs_0900_as_cs与utf8mb4_0900_as_cs排序规则差异问询
MySQL utf8mb4_cs_0900_as_cs与utf8mb4_0900_as_cs排序规则差异解析
在为SQLAlchemy接口编写单元测试时,遇到MySQL字符串列排序结果不符合预期的问题。排查发现当前数据库使用utf8mb4_cs_0900_as_cs排序规则,切换为utf8mb4_0900_as_cs后排序结果恢复正常。
测试示例
mysql> SELECT -> column_0 AS name1 -> FROM -> (VALUES -> ROW('default_chanakah'), -> ROW('default_aaa'), -> ROW('default_zzz'), -> ROW('default_hsunan'), -> ROW('default_kourin1') -> ) AS hardcodedNames -> ORDER BY -> name1 -> COLLATE utf8mb4_cs_0900_as_cs; +------------------+ | name1 | +------------------+ | default_aaa | | default_hsunan | | default_chanakah | | default_kourin1 | | default_zzz | +------------------+ 5 rows in set (0.00 sec) mysql> SELECT -> column_0 AS name1 -> FROM -> (VALUES -> ROW('default_chanakah'), -> ROW('default_aaa'), -> ROW('default_zzz'), -> ROW('default_hsunan'), -> ROW('default_kourin1') -> ) AS hardcodedNames -> ORDER BY -> name1 -> COLLATE utf8mb4_0900_as_cs; +------------------+ | name1 | +------------------+ | default_aaa | | default_chanakah | | default_hsunan | | default_kourin1 | | default_zzz | +------------------+ 5 rows in set (0.00 sec)
两种排序规则的核心差异
MySQL排序规则命名遵循字符集_版本_属性的格式,先拆解共性部分:
utf8mb4:支持完整Unicode的字符集(包含4字节字符如emoji)0900:基于Unicode 9.0.0版本的排序算法as:区分重音(Accent-Sensitive)cs:区分大小写(Case-Sensitive)
两者的关键区别在于规则类型:
utf8mb4_0900_as_cs:标准Unicode排序规则,严格遵循Unicode 9.0的字典序逻辑,字符比较权重符合通用认知(如a < c < h < k < z),所以测试中得到的是符合预期的排序结果。utf8mb4_cs_0900_as_cs:属于兼容型排序规则,这类规则是为了适配旧系统或特定兼容场景设计的,会对部分字符的权重分配做非标准调整。从测试结果可以看到,default_hsunan排在了default_chanakah前面,就是因为这类规则没有严格遵循标准字典序,而是采用了特殊的比较逻辑,导致排序结果偏离预期。
建议
在MySQL 8.0及以上版本中,优先使用utf8mb4_0900_as_cs这类标准Unicode排序规则,它的排序行为更符合通用预期;仅在需要适配旧系统遗留行为时,才考虑使用utf8mb4_cs_0900_as_cs这类兼容规则。
内容的提问来源于stack exchange,提问作者LDevelop
相关产品推荐
相关产品推荐

