17.3. 区域支持
注意
由 Oleg Bartunov 撰写。关于区域和俄语支持的更多信息,请见Oleg 的网页。
在为俄罗斯莫斯科的一家公司做项目时,我遇到了 postgresql 不支持国家字母表的问题。在寻找可能的变通办法之后,我决定自己开发区域支持。我不是 C 程序员,但在使用 perl(调试)和
glimpse 工作时已经有一些区域编程的经验。在
Postgres源码树中挖掘了几天之后,我对
src/backend/utils/adt/varlena.c 和 src/backend/main/main.c 做了非常小的修改,就得到了我需要的东西!我当时只做了
LC_CTYPE和LC_COLLATE的支持,但后来其他人又添加了LC_MONETARY。我收到许多人关于这个补丁的消息,因此我决定把它发给开发者,而(让我惊讶的是)它被并入了Postgres
发行版。
人们经常抱怨区域支持对他们不起作用。有几种常见的错误:
编译之前没有正确配置 postgresql。必须用 --enable-locale 选项运行 configure 来启用区域支持。启动 postmaster 时没有正确设置环境。必须在运行 postmaster 之前定义环境变量
LC_CTYPE和LC_COLLATE,因为后端从环境中获取区域信息。我使用下面的 shell 脚本(runpostgres):#!/bin/sh export LC_CTYPE=koi8-r export LC_COLLATE=koi8-r postmaster -B 1024 -S -D/usr/local/pgsql/data/ -o '-Fe'并从 rc.local 中这样运行它:
/bin/su - postgres -c "/home/postgres/runpostgres"操作系统的区域支持损坏(例如,Linux 下 libc 的区域支持曾多次变化,这引起了很多问题)。最新的 perl 也支持区域,如果区域损坏,
perl -v会抱怨类似下面的内容:8:17[mira]:~/WWW/postgres>setenv LC_CTYPE not_exist 8:18[mira]:~/WWW/postgres>perl -v perl: warning: Setting locale failed. perl: warning: Please check that your locale settings: LC_ALL = (unset), LC_CTYPE = "not_exist", LANG = (unset) are supported and installed on your system. perl: warning: Falling back to the standard locale ("C").区域文件的位置错误!可能的位置包括:
/usr/lib/locale(Linux, Solaris),/usr/share/locale(Linux),/usr/lib/nls/loc(DUX 4.0). 请查看man locale以找到正确的位置。在 Linux 下,我在/usr/lib/locale和/usr/share/locale之间做了一个符号链接,以确保下一个 libc 不会破坏我的区域。
17.3.1. 有什么好处?
可以对包含国家字母表字符的字符串使用 ~* 和 order by 操作符。非英语用户肯定需要它。如果你不想使用区域相关的东西,只需取消定义 USE_LOCALE 变量。
17.3.2. 有什么缺点?
使用区域有一个明显的缺点——速度!所以,只在真正需要时才使用区域。