List of databases
Name | Owner | Encoding | Collate | Ctype |
-------------------------+----------+----------+----------------------------+----------------------------|
MyDatabase | postgres | UTF8 | English_United States.1252 | English_United States.1252 |
有人能解释一下 Encoding、Collate 和 Ctype 是如何相互关联的吗?
我知道编码会影响信息的实际存储方式(即“A”是否需要一个字节或多个字节,以及这些字节的值取决于编码)。
我被告知 collate 指定了比较字符的规则。如果您要对一堆字符串进行排序,则整理类型将决定顺序。
我一直在努力寻找 Ctype 是什么;可能与大写和小写等概念有关(假设 'a' 知道 'A' 是大写形式?)。
我不明白(如在我的示例中)我如何拥有一个 UTF8 编码的数据库并使用英语 1252 的校对值。UTF8 有许多 win1252 没有的字符;如果我尝试对它们进行排序或比较会发生什么?我当前的设置是荒谬的......似乎我总是希望 Encoding/Collate/Ctype 同意?
是的。编码是字符到字节的转换算法。对于像 LATIN1 这样的单字节编码,它通常是字节值 = 字符数,但对于 UTF-8,它更复杂。
是的,collate 指定如何比较字符串。排序服务由操作系统提供,或者可选地由 PostgreSQL 10 或更高版本的 ICU 库提供。使用语言规则对任意字符串进行排序是一项复杂的工作。Unicode 标准和 ISO 提供了规则,但它们是高度可定制的,而且并非所有 C 库都完全实现它们。有关更多信息,请参见例如https://en.wikipedia.org/wiki/Unicode_collation_algorithm 。
POSIX 中的 LC_CTYPE 与ctype.h中的函数有关 Postgres 在这方面受到 POSIX 的强烈影响,并且
lc_ctype
或多或少像 POSIX 使用的那样使用每个数据库LC_CTYPE
。除了 upper() 和 lower(),它还与正则表达式和全文搜索(标记的大小写折叠)相关。
我认为 Postgres 可以不使用独立的 lc_ctype(使用与 lc_collate 相同的值),除了一件事:有趣的是
lc_ctype
,必须something.UTF-8
正确支持所有字符,并且 因为 C 作为排序规则很多比 . 所暗示的任何语言排序都快。lc_collate
C
lc_collate=lang_country.UTF-8
当在 Postgres 中增强 COLLATE 支持时,Robert Haas(postgres 提交者)写了一篇关于该主题的有趣帖子:“排序感知比较的风险”
这是一个特定于 Windows 的事情,因为 Windows 不遵循带有语言环境和排序规则的 POSIX 模型。在 Windows 和非 ICU 排序规则中,Postgres 会将字符串从 db 编码转换为 UTF-16 (
wchar_t
) 并调用wcscoll_l()。这就是编码与排序规则去相关的原因。使用 ICU 排序规则,Postgres 可以直接传递 UTF-8 内容,或者将字符串转换为 UTF-16,因此排序规则再次与特定的数据库编码无关,这与 POSIX 模型及其 strcoll 函数系列相反。