文档章节

PG中locale与消息的设置

YuanyuanL
 YuanyuanL
发布于 2015/03/17 15:14
字数 4043
阅读 126
收藏 0

官方文档:英文:http://www.postgresql.org/docs/9.2/static/charset.html

                 中文:http://58.58.27.50:8079/doc/html/9.3.1_zh/charset.html

pg中的本地化消息设置:http://blog.chinaunix.net/uid-20726500-id-4675473.html

linux下的locale设置: http://blog.chinaunix.net/uid-26760055-id-3222699.html


locale中文翻译成区域,其实这个单词包含的意义要宽泛很多。Locale是根据计算机用户所使用的语言,所在国家或者地区,以及当地的文化传统所定义的一个软件运行时的语言环境。

  1. 操作系统的locale设置(以linux为例)

    操作系统环境变量针对语言项设置有几个,经常设置的是这两个LANG和NLS_LANG。LANG是针对Linux系统的语言、地区、字符集的设置,对linux下的应用程序有效(包括postgresql),如date;NLS_LANG是针对Oracle语言、地区、字符集的设置,对oracle中的工具有效。

       Linux系统中关于环境变量的LANG设置主要有下列项目:

[root@lyy bin]#export LANG='zh_CN.gb2312'
[root@lyy bin]#echo $LANG
zh_CN.gb2312
[root@lyy bin]# locale
LANG=zh_CN.gb2312
LC_CTYPE="zh_CN.gb2312"
LC_NUMERIC="zh_CN.gb2312"
LC_TIME="zh_CN.gb2312"
LC_COLLATE="zh_CN.gb2312"
LC_MONETARY="zh_CN.gb2312"
LC_MESSAGES="zh_CN.gb2312"
LC_PAPER="zh_CN.gb2312"
LC_NAME="zh_CN.gb2312"
LC_ADDRESS="zh_CN.gb2312"
LC_TELEPHONE="zh_CN.gb2312"
LC_MEASUREMENT="zh_CN.gb2312"
LC_IDENTIFICATION="zh_CN.gb2312"
LC_ALL=

        这里LC_ALL没有设置,如果它设置了,上面所有的设置都无效的,系统会读取LC_ALL。

        查看本地字符集:

[root@lyy bin]#locale -a

       查看所有支持的字符集:

[root@lyy bin]#locale -m

locale把按照所涉及到的文化传统的各个方面分成12个大类,这12个大类分别是:

1、语言符号及其分类(LC_CTYPE) 
2、数字(LC_NUMERIC) 
3、比较和排序习惯(LC_COLLATE) 
4、时间显示格式(LC_TIME) 
5、货币单位(LC_MONETARY) 
6、信息主要是提示信息,错误信息,状态信息,标题,标签,按钮和菜单等(LC_MESSAGES) 
7、姓名书写方式(LC_NAME) 
8、地址书写方式(LC_ADDRESS) 
9、电话号码书写方式(LC_TELEPHONE) 
10、度量衡表达方式 (LC_MEASUREMENT) 
11、默认纸张尺寸大小(LC_PAPER) 
12、对locale自身包含信息的概述(LC_IDENTIFICATION)。

  设定locale就是设定12大类的locale分类属性,即12个LC_*。除了这12个变量可以设定以外,为了简便起见,还有两个变量:LC_ALL和LANG。它们之间有一个优先级的关系:LC_ALL > LC_* >LANG可以这么说,LC_ALL是最上级设定或者强制设定,而LANG是默认设定值。 
  1、如果你设定了LC_ALL=zh_CN.UTF-8,那么不管LC_*和LANG设定成什么值,它们都会被强制服从LC_ALL的设定,成为 zh_CN.UTF-8。 
  2、假如你设定了LANG=zh_CN.UTF-8,而其他的LC_*=en_US.UTF-8,并且没有设定LC_ALL的话,那么系统的locale设定以LC_*=en_US.UTF-8。 
  3、假如你设定了LANG=zh_CN.UTF-8,而其他的LC_*,和LC_ALL均未设定的话,系统会将LC_*设定成默认值,也就是LANG的值zh_CN.UTF-8。 
  4、假如你设定了LANG=zh_CN.UTF-8,而其他的LC_CTYPE=en_US.UTF-8,其他的LC_*,和LC_ALL均未设定的话, 那么系统的locale设定将是:LC_CTYPE=en_US.UTF-8,其余的 LC_COLLATE,LC_MESSAGES等等均会采用默认值,也就是 LANG的值,也就是LC_COLLATE=LC_MESSAGES=……= LC_PAPER=LANG=zh_CN.UTF-8。 
   所以,locale是这样设定的: 
  1、如果你需要一个纯中文的系统的话,设定LC_ALL= zh_CN.XXXX,或者LANG=zh_CN.XXXX都可以,当然你可以两个都设定,但正如上面所讲,LC_ALL的值将覆盖所有其他的locale设定,不要作无用功。 
  2、如果你只想要一个可以输入中文的环境,而保持菜单、标题,系统信息等等为英文界面,那么只需要设定 LC_CTYPE=zh_CN.XXXX,LANG=en_US.XXXX就可以了。这样LC_CTYPE=zh_CN.XXXX,而LC_COLLATE=LC_MESSAGES=……= LC_PAPER=LANG=en_US.XXXX。 
  3、假如你高兴的话,可以把12个LC_*一一设定成你需要的值,打造一个古灵精怪的系统: LC_CTYPE=zh_CN.GBK/GBK(使用中文编码内码GBK字符集); LC_NUMERIC=en_GB.ISO-8859-1(使用大不列颠的数字系统) LC_MEASUREMEN=de_DE@euro.ISO-8859-15(德国的度量衡使用ISO-8859-15字符集) 罗马的地址书写方式,美国的纸张设定……。估计没人这么干吧。 
  4、假如你什么也不做的话,也就是LC_ALL,LANG和LC_*均不指定特定值的话,系统将采用POSIX作为lcoale,也就是C locale。

     另外LANG和LANGUAGE有什么区别呢?
     LANG - Specifies the default locale for all unset locale variables
     LANGUAGE - Most programs use this for the language of its interface
     LANGUAGE是设置应用程序的界面语言。而LANG是优先级很低的一个变量,它指定所有与locale有关的变量的默认值。

     locale设置的含义:

    zh_CN.UTF-8 表示语言为中文,地区为中国,编码为UTF-8 (操作系统语言是中文,初次设置可能需要重启)

    en_US.UTF-8 表示语言为英文,地区为美国,编码为UTF-8 (操作系统语言是英文,初次设置可能需要重启)   

    环境变量的三个设置方法及其生命期

     Linux下:echo $paraName = paraValue ,                                              临时定义,只在该登陆操作内有效

                    在特定用户目录下的.bashrc(该文件是隐藏文件,用ls -al才能看到)文件中添加paraName=paraValue, 只对该用户登录时有效

                    在/etc/profile文件中添加paraName=paraValue,                      对系统中所有用户都有效

                   (以上若在终端操作,则终端语言会接着就改变了)

2.pg中的locale属性设置

2.1. 区域支持

    区域支持指的是应用中考虑字母、排序、数值格式化等与文化相关的问题。 PostgreSQL使用服务器操作系统提供的标准ISO C 和POSIX区域机制。 更多的信息请参考你的系统文档。

2.1.1. 概述     

    区域支持是在使用initdb创建一个数据库集群的时候自动初始化的。 缺省时,initdb将会按照它的执行环境的区域设置初始化数据库集群; 因此如果你的系统已经设置为你的数据库集群想要的区域,那么你就没有什么可干的了。 如果你想使用其它的区域(或者你还不知道你的系统设置的区域是什么), 那么你可以用--locale命令行选项告诉initdb你需要的区域究竟是哪个。 比如:

      initdb --locale=sv_SE

     Unix系统下的这个例子就把区域设置为说瑞典语(sv),并且在瑞典地区(SE)。 其它的可能性是en_US(美国英语)和fr_CA(加拿大法语)等等。 如果有多于一种的字符集可以用于同一个区域,那么声明看起来会像language_territory.codeset。 比如,fr_BE.UTF-8表示为在比利时(BE)地区使用的法语(fr),并且使用UTF-8字符集编码。

     你的系统里有哪些可用的区域设置,它们的名字是什么, 这些信息都取决于你的操作系统提供商提供了什么以及你安装了什么东西。 在大多数系统上,命令locale -a将提供所有可用区域的一个列表。 Windows使用更详细的区域名称,比如German_Germany或者Swedish_Sweden.1252, 但是原则是一样的。

     有时候,把几种区域规则混合起来也很有用,比如, 使用英语排序规则而用西班牙语消息。为了支持这些, 我们有一套区域子范畴用于控制区域规则的某一方面:

    LC_COLLATE字符串排序顺序

    LC_CTYPE字符分类(什么是字母?是否区分大小写?)

    LC_MESSAGES消息的语言

    LC_MONETARY货币金额的格式

    LC_NUMERIC数值格式

    LC_TIME日期和时间格式

     这些范畴名转换成initdb选项的名字以覆盖某个特定范畴的区域选择。 比如,要把区域设置为加拿大法语,但使用美国的货币格式化规则, 可以使用initdb --locale=fr_CA --lc-monetary=en_US。

     如果你想要你的系统表现得像没有区域支持一样,那么使用特殊的区域C或POSIX。一些区域范畴的值必须在创建数据库时固定下来。 您可以对不同的数据库使用不同的设置,但一旦创建一个数据库,你就再也不能更改它们了。 LC_COLLATE和LC_CTYPE就是这样的范畴。 它们影响索引的排序顺序,因此它们必需保持固定,否则在文本字段上的索引将会崩溃。 (但是你可以使用排序规则(collation)缓解这种限制,正如Section 22.2中讨论的)。 当运行initdb时确定这些范畴的缺省值, 这些值被用于创建新的数据库,除非在CREATE DATABASE命令中明确指定。

    其它区域范畴可以在服务器启动的时候根据需要设置 服务器配置参数来改变(参阅Section 18.11.2获取细节)。 initdb选择的值实际上只是作为服务器启动时的缺省值写入 postgresql.conf配置文件。 如果你在postgresql.conf里面删除了这些设置, 那么服务器将会继承来自运行环境的设置。 

    请注意服务器的区域行为是由它看到的环境变量决定的, 而不受客户端的环境影响。 因此,我们要在启动服务器之前认真地设置好这些变量。 这样带来的一种情况是如果客户端和服务器设置成不同的区域, 那么消息可能以不同的语言呈现,这取决于消息的来源。

     Note: 在我们谈到从执行环境继承区域的时候, 我们的意思是在大多数操作系统上的下列动作: 对于一个给定的区域范畴, 比如排序规则,按照下面的顺序评估这些环境变量, 直到找到一个已设置的:LC_ALL, LC_COLLATE (或者对应于相应范畴的其他变量), LANG。 如果这些环境变量一个都没有设置,那么区域缺省为C。

     一些消息本地化库也使用环境变量LANGUAGE, 它覆盖所有其它用于设置语言信息的区域设置。 如果有问题,请参考你的操作系统文档, 特别是gettext的文档以获取更多信息。

     要能够将消息翻译成用户选择的语言,编译时必需选择NLS选项(configure --enable-nls)。 其它区域支持是自动包含的。

22.1.2. 行为

区域设置特别影响下面的 SQL 特性:

     1 查询中使用ORDER BY或者对文本数据的标准比较操作符进行排序

     2 upper, lower和initcap函数模式匹配运算符(LIKE, SIMILAR TO, 以及POSIX-风格的正则表达式); 区域影响大小写不敏感的匹配和通过字符分类正则表达式的字符分类。

     3 to_char函数族

     4 使用LIKE子句的索引能力

    PostgreSQL里使用非C或者POSIX区域的缺点是性能影响。 它降低了字符处理的速度并阻止了在LIKE类查询里面普通索引的使用。 因此,应该只有在你实际上需要的时候才使用它。

    为了允许PostgreSQL在非C区域下的LIKE子句中使用索引, 有好几个自定义的操作符类可以用。 这些操作符类允许创建一个严格地比较每个字符的索引, 而忽略区域比较规则。请参考Section 11.9获取更多信息。 另外一个方法是使用C collation创建索引,正如Section 22.2 中讨论的。

22.1.3. 问题

      如果经过上面解释后区域支持仍然不能运转, 那你就要检查一下操作系统的区域支持是否正确配置。 要检查某个区域是否安装并且正常运转, 你可以使用locale -a命令(如果你的系统提供了该命令)。

     请检查核实PostgreSQL确实使用了你认为它该用的区域设置。 LC_COLLATE和LC_CTYPE的设置都是在数据库创建时决定的, 不能被改变除非创建新的数据库。其它的区域设置包括 LC_MESSAGES和LC_MONETARY都是由服务器的启动环境决定的, 但是可以在运行时修改。你可以用SHOW命令检查数据库正在使用的区域设置。

     源码发布中的src/test/locale目录包含 PostgreSQL的区域支持测试套件。

      那些通过解析错误消息文本处理服务器端错误的客户端应用很明显会有问题, 因为服务器信息可能会以不同的语言表示。我们建议这类应用的开发人员改用错误代码机制。

     维护消息翻译表需要许多志愿者的坚持不懈的努力, 他们就是希望PostgreSQL以他们的语言说话的人。 如果你的语言消息目前还不可用或者没有完全翻译完成, 那么我们很欢迎你的协助。如果你想帮忙, 那么请参考Chapter 50或者向开发者邮递列表发邮件。


3.小总结

pg的语言一开始是根据OS的locale的。OS的locale设置是根据LC_ALL > LC_* > LANG 的优先级来设置的:如果定义了LC_ALL那么LC_*均与LC_ALL保持一致,LANG不起作用;如果LC_ALL和LC_*均未设置,那么设置LANG后,LC_ALL和LC_*将使用默认值LANG

        Linux下环境变量的三种设置方法及其生命期:

             echo $paraName = paraValue ,                                              临时定义,只在该登陆操作内有效

             在特定用户目录下的.bashrc(该文件是隐藏文件,用ls -al才能看到)文件中添加paraName=paraValue, 只对该用户登录时有效

             在/etc/profile文件中添加paraName=paraValue,                      对系统中所有用户都有效

            (以上若在终端操作,则终端语言会紧接着生效)

DB初始化后一部分local属性在初始化时确定了下来(LC_COLLATE和LC_CTYPE在数据库初始化后便不能再修改(server_encoding也不能修改,他们都能通过sql语句show出来)其他的可以在运行中修改),初始化完成后查看postgresql.conf中的locale相关参数,已指定的会体现出来,未指定的就是使用的默认值;如果想要数据库系统没有区域限制,那么使用特殊的区域C或POSIX来初始化。

pg的消息的语言是由lc_messages设置的。设置OS的locale为en_us.UTF8会使得psql的运行环境成为英文的;设置lc_messages='c'可以使得服务器的消息为英文,能保证各种中间件得到的消息不会成为乱码。

         在pg中locale项的两种设置方式及其生命期

          sql下set lc_messages='zh_CN.UTF-8'仅对该登陆起效,

         要想使得配置永久生效,需要在/data/postgresql.conf总添加lc_messages='zh_CN.UTF-8',保存后,重启服务或者重载。

[lyy@linux bin]$ export LANG=zh.CN.UTF-8     --设置操作系统语言为中文
[lyy@linux bin]$ ./psql                      --登陆数据库之前语言是中文
口令:
psql(9.2.1)
输入“help”来获取帮助信息。
lyy=# show lc_messages;
lc_messages
------------------
C
(1行记录)                                    --lc_messages值为C,登陆数据库后消息语言还是中文
lyy=# show server_encoding;
server_encoding
------------------
UTF-8
(1行记录)
lyy=# show client_encoding;
server_encoding
------------------
UTF-8
(1行记录)
lyy=# \q
[lyy@linux bin]$ export  LANG=en_US.UTF-8    --设置操作系统语言为英文
[lyy@linux bin]$ ./psql
Password:                                   --登陆数据库之前语言是英文
psql(9.2.1)
Type“help” for help.
lyy=# show lc_messages;                     
lc_messages
------------------
C
(1 row)                                       --lc_messages值为C,登陆数据库后消息语言还是英文
lyy=# set lc_messages='zh_CN.UTF-8';          --lc_messages值修改为中文,数据库消息变为中文
SET
lyy=# dd;
错误: 与犯错误 在“DD”或附近
LINE 1:DD

 

  常见乱码情况:JDBC中,消息都转为UTF8,但是连接错误容易出乱码,因为那时候客户端还不知道服务器的编码,不能进行编码转换,所以如果消息不是UTF8的就会乱,只有恰巧也是UTF8的才会不是乱码。

© 著作权归作者所有

共有 人打赏支持
YuanyuanL

YuanyuanL

粉丝 154
博文 325
码字总数 190992
作品 0
济南
部门经理
私信 提问
intall postgresql 9.1 on CentOS

http://people.planetpostgresql.org/devrim/index.php?/archives/48-What-is-new-in-PostgreSQL-9.0-RPMs.html # rpm -Uvh http://download.fedoraproject.org/pub/epel/6/i386/epel-releas......

mark35
2012/03/01
0
0
PostgreSQL数据类型-货币类型

PostgreSQL支持货币(money)类型,在内存中占用8 位空间,表示范围-92233720368547758.08 to +92233720368547758.07,有别于变精度浮点类型real 和 double precision,和numeric有些相似,都...

白豆腐徐长卿
2017/11/07
0
0
Confluence 6 安装 PostgreSQL

如果你的系统中还没有安装 PostgreSQL 数据库,你需要先下载后进行安装。 在安装 PostgreSQL 时候的一些小经验: 在安装的时候提供的 密码(password )是针对 'postgres' 账户的,这个账户是...

honeymose
2018/06/01
0
0
通过源码编译安装PostgreSQL步骤及问题总结

今天博主在ubuntu 10.04安装从enterprisedb下载的postgresql安装包是出现一个问题,运行后提示“Segmentation fault”错误,安装失败。之前我在12.04版的系统中有安装过,一切正常。之后公司...

章郎虫
2014/01/15
0
0
Windows7安装PostgreSQL 8.4或以上版本出错解决办法

在Vista或者Windows7上安装Postgresql 8.4或者Postgresql 9.0,到了最后的关头总是出错!提示错误信息是:database cluster initialization failed。也许很沮丧吧?但是看一下错误,就知道为...

华宰
2011/04/16
1K
7

没有更多内容

加载失败,请刷新页面

加载更多

OSChina 周六乱弹 —— 看见这花臂了么?赶紧叫大佬!

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @宇辰OSC :分享周华健的单曲《有没有一首歌会让你想起我》 《有没有一首歌会让你想起我》- 周华健 手机党少年们想听歌,请使劲儿戳(这里) ...

小小编辑
今天
89
4
Confluence 6 升级中的一些常见问题

升级的时候遇到了问题了吗? 如果你想尝试重新进行升级的话,你需要首先重新恢复老的备份。不要尝试再次对 Confluence 进行升级或者在升级失败后重新启动老的 Confluence。 在升级过程中的一...

honeymoose
今天
2
0
C++随笔(四)Nuget打包

首先把自己编译好的包全部准备到一个文件夹 像这样 接下来新建一个文本文档,后缀名叫.nuspec 填写内容 <?xml version="1.0"?><package xmlns="http://schemas.microsoft.com/packaging/201......

Pulsar-V
今天
3
0
再谈使用开源软件搭建数据分析平台

三年前,我写了这篇博客使用开源软件快速搭建数据分析平台, 当时收到了许多的反馈,有50个点赞和300+的收藏。到现在我还能收到一些关于dataplay2的问题。在过去的三年,开源社区和新技术的发...

naughty
今天
19
0
Python3的日期和时间

python 中处理日期时间数据通常使用datetime和time库 因为这两个库中的一些功能有些重复,所以,首先我们来比较一下这两个库的区别,这可以帮助我们在适当的情况下时候合适的库。 在Python文...

编程老陆
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部