Postgres - 编码、整理和 CType

Rob*_* P. 11 postgresql encoding localization

                                                        List of databases 
          Name           |  Owner   | Encoding |          Collate           |           Ctype            |
-------------------------+----------+----------+----------------------------+----------------------------|
 MyDatabase              | postgres | UTF8     | English_United States.1252 | English_United States.1252 |
Run Code Online (Sandbox Code Playgroud)

有人能解释一下编码、整理和 Ctype 是如何相互关联的吗?

我知道编码会影响信息的实际存储方式(即“A”需要一个字节还是多个字节,以及这些字节的值取决于编码)。

有人告诉我 collat​​e 指定比较字符的规则。如果要对一堆字符串进行排序,则整理类型将决定顺序。

我一直在努力寻找 Ctype 是什么;可能与大写和小写等概念有关(假设 'a' 知道 'A' 是大写形式?)。

我不明白(如在我的示例中)我如何拥有一个 UTF8 编码的数据库并使用英语 1252 的校对值。UTF8 有很多 win1252 没有的字符;如果我尝试对它们进行排序或比较会发生什么?我当前的设置是荒谬的......似乎我总是希望编码/整理/Ctype 同意?

Dan*_*ité 11

我知道编码会影响信息的实际存储方式(即“A”需要一个字节还是多个字节,以及这些字节的值取决于编码)。

是的。编码是字符到字节的转换算法。对于像 LATIN1 这样的单字节编码,字节值 = 字符数很简单,但对于 UTF-8 来说就更复杂了。

有人告诉我 collat​​e 指定比较字符的规则。如果要对一堆字符串进行排序,则整理类型将决定顺序。

是的,collat​​e 指定如何比较字符串。整理服务由操作系统提供,或者由 PostgreSQL 10 或更新版本的 ICU 库提供。使用语言规则对任意字符串进行排序是一项复杂的工作。Unicode 标准和 ISO 提供了规则,但它们是高度可定制的,而且并非所有 C 库都完全实现了它们。例如 ,请参阅https://en.wikipedia.org/wiki/Unicode_collat​​ion_algorithm了解更多信息。

我一直在努力寻找 Ctype 是什么;可能与大写和小写等概念有关(假设 'a' 知道 'A' 是大写形式?)。

POSIX 中的 LC_CTYPE 与ctype.h 中的函数有关 Postgres 在这方面受到 POSIX 的强烈影响,并且lc_ctype或多或少像 POSIX 使用的那样使用每个数据库LC_CTYPE

除了 upper() 和 lower() 之外,它还与正则表达式和全文搜索(标记的大小写折叠)相关。

我认为,Postgres的可能没有一个独立的LC_CTYPE做(使用相同的值LC_COLLATE),除了一两件事:它们也同样吸引有lc_ctypesomething.UTF-8例如,有充分的字符范围适当的支持,以及 lc_collateC因为C作为排序规则是多少比lc_collate=lang_country.UTF-8.

Robert Haas(postgres 提交者)在 Postgres 中增强了 COLLATE 支持时写了一篇关于该主题的有趣文章:“整理感知比较的危险”

我不明白(如在我的示例中)我如何拥有一个 UTF8 编码的数据库并使用英语 1252 的校对值。UTF8 有很多 win1252 没有的字符

这是特定于 Windows 的事情,因为 Windows 没有遵循具有语言环境和排序规则的 POSIX 模型。在 Windows 和非 ICU 排序规则中,Postgres 会将字符串从 db 编码转换为 UTF-16 ( wchar_t) 并调用wcscoll_l()。这就是编码与排序规则去相关的原因。

对于 ICU 排序规则,Postgres 要么直接传递 UTF-8 内容(如果可以),要么将字符串转换为 UTF-16,因此排序规则与特定的数据库编码无关,这与 POSIX 模型及其 strcoll 函数系列相反。