PostgreSQL UTF-8 二进制排序规则

Posted

技术标签:

【中文标题】PostgreSQL UTF-8 二进制排序规则【英文标题】:PostgreSQL UTF-8 binary collation 【发布时间】:2011-12-08 09:17:29 【问题描述】:

我希望有一个排序规则,它将 0x1234 的 UTF-8 编码排序在 0x1235 之下,而不管 Unicode 标准中的字符映射如何。 mysql 为此使用 utf8_bin。 MSSQL 显然 http://msdn.microsoft.com/en-us/library/ms143350.aspx 有 BIN 和 BIN2 排序规则。虽然找到这些很容易,但我什至找不到 PostgreSQL 支持的排序规则列表,对这个特定问题的回答要少得多。

【问题讨论】:

【参考方案1】:

C 语言环境可以。 UTF-8 的设计使得字节排序也是代码点排序。这不是微不足道的,但请考虑一下 UTF-8 的工作原理:

编号范围 字节 1 字节 2 字节 3 0000-007F 0xxxxxxx 0080-07FF 110xxxxxx 10xxxxxx 0800-FFFF 1110xxxx 10xxxxxx 10xxxxxx

在对二进制数据(也称为 C 语言环境)进行排序时,第一个不相等的字节将决定排序。我们需要看到的是,如果编码为 UTF-8 的两个数字不同,那么第一个不相等的字节对于较低的值将较低。如果数字在不同的范围内,那么对于较低的数字,第一个字节确实会较低。在相同的范围内,顺序由字面上与不编码时相同的位确定。

【讨论】:

这是一种代码点排序,在 Unicode 上完全没用。您如何使用 Unicode 在其 Unicode Collat​​ion Algorithm 中要求的排序算法进行正确的字母排序? @tchrist:这不是问题。【参考方案2】:

文本的排序顺序取决于lc_collate(不是系统区域设置!)。如果您不提供其他语言环境,则系统语言环境仅在创建数据库集群时用作默认设置。

您所期望的行为仅适用于语言环境C。阅读所有相关信息in the fine manual:

C 和 POSIX 排序规则都指定“传统 C”行为,在 只有 ASCII 字母“A”到“Z”被视为字母, 严格按照字符代码字节值进行排序

强调我的。 PostgreSQL 9.1 有几个new features for collation。可能正是您正在寻找的。​​p>

【讨论】:

如何让它进行字母排序而不是代码点排序?您知道,因此它使用了 Unicode 排序算法。否则,您将永远无法对 Unicode 文本进行字母排序。 @tchrist:通常您将lc_collate 设置为您的语言环境。示例:在英格兰,您可能会将lc_collate 设置为en_EN.utf8。尝试SHOW lc_collate; 查看您的设置。请按照我的答案中的链接了解更多信息。【参考方案3】:

Postgres 在创建集群时使用系统语言环境定义的排序规则。

您可以尝试 ORDER BY encode(column,'hex')

【讨论】:

以上是关于PostgreSQL UTF-8 二进制排序规则的主要内容,如果未能解决你的问题,请参考以下文章

向 PostgreSQL 添加不区分大小写的排序规则

PostgreSQL 是不是支持“不区分重音”排序规则?

Postgresql 排序语言特定字符(排序规则)

在 PostgreSQL 中安装 utf8 排序规则

对于可能以不同语言使用的 PostgreSQL 数据库,正确的排序规则是啥?

postgresql某个字段值按照指定规则排序