Redrock Postgres 文档
主页 切换暗/亮/自动模式 切换暗/亮/自动模式 切换暗/亮/自动模式 返回首页
编辑页面

为什么我的字符串排序不正确?

问题描述

为什么我的字符串排序不正确?

问题解答

首先,确保您使用的是要使用的区域设置。使用SHOW lc_collate显示当前的数据库级别的区域设置。如果您在使用每列排序规则,请检查这些排序规则。如果一切都是您想要的,请继续阅读。

PostgreSQL 使用libc库的区域能力来对字符串进行排序。因此,如果字符串的排序顺序不是您所期望的,则问题可能出在libc库中。您可以使用文本文件上的sort实用程序验证libc库的排序思路,例如:

LC_COLLATE="zh_CN.UTF-8" sort testfile.txt

如果这导致与 PostgreSQL 相同的顺序,那么问题来自于 PostgreSQL 之外。

PostgreSQL 偏离了libc的行为,因为它通过按字节顺序对字符串进行排序而打破了联系。这在实践中应该很少产生影响,并且当用户抱怨排序顺序时通常不是问题的根源,但它可能会影响例如组合和预组合的 Unicode 字符混合的情况。

如果问题出在libc库中,则必须与操作系统维护人员一起解决。但是请注意,即使确认libc库的区域设置定义中存在实际错误,但更有可能的是libc库是正确的,其中“正确”意味着它遵循一些公认的国际或国家标准。您可能期望对语言的排序规则的多种同样有效的解释之一。

用户经常反馈的问题包括:

  • 空格和特殊字符:排序算法通常在多个传递中工作。我们可以这样简单地理解:首先,比较所有字母,忽略空格和标点符号;然后,将空格和标点符号进行比较以排除影响。如果不更改区域设置定义本身,就不可能更改这个排序的行为(即使这样也很困难)。您可能需要稍微调整数据以避免此问题。例如,如果要对名称字段进行排序,则可以将该字段拆分为名字和姓氏字段,避免中间的空格。

  • 大小写:除C以外的区域设置通常将大写和小写字母排序在一起。所以顺序将是类似于 “a A b B c C …",而不是基于 ASCII 字节值的排序给出 “A B C … a b c …"。这是正确的。

  • 它不是按 ASCII/字节顺序排列的。不是的,也不应该。ASCII 是一种编码,而不是排序顺序。如果需要,可以使用C区域设置,但这样就失去了根据具体语言对非 ASCII 字符进行排序的能力。