PG支持客户端和服务器端编码方式设置,如果两端编码一样,则在存取时不进行任何转换;如果不一样则自动进行转换。但其支持的有些编码只能用在服务端,不能用在客户端。
详细可参考其官方文档 http://www.postgresql.org/docs/9.2/interactive/multibyte.html 。支持简体中文有四种编码:EUC_CN(Extended UNIX Code-CN)、GB18030、GBK和UTF-8。但GB18030和GBK只能作为客户端编码,不能设置为服务端编码;由于Windows上又不支持EUC_CN编码,所以在Windows上服务端编码只能设为UTF-8。
下面通过两个简单的示例,来说明其编码转换过程。
数据:表test,字段name,类型text
示例一 客户端编码和服务端编码之间的转换(使用psgl)
1、服务端编码为UTF-8,客户端工具psgl默认为GBK
2、在此环境下插入“汉字”,一切正常。此时传到客户的“汉字”为GBK编码,自动转为UTF-8编码存到服务端;而查询时,又自动将服务端的UTF-8编码转为GBK来显示,所以没有出现乱码。
3、将客户端编码设置为UTF-8,则刚才插入的“汉字”不能正常显示。因为此时客户端和服务端的编码一样,在取数据时不进行任何转换,直接将存在服务端的UTF8编码的字节传到客户端,之后psgl直接显示,所以就乱码了。
4、在此环境下插入“汉字”,则添加不成功,因为“汉字”直接以GBK的形式传到服务端,UTF8编码不认识,所以就报错。(现在客户端编码为UTF8,所以提示的中文信息也乱码了)。
总结:1、在此示例中,应用程序psgl,对所输入和获取的字符没做任何处理,直接显示,其使用了pg客户端一样的编码方式(GBK)。
2、在使用时尽量保证客户端编码和操作系统环境一致,不然显示和添加就会出现乱码情况。
示例二 应用程序、客户端和服务端编码转换(pgAdmin3可视化界面)
pgAdmin3内部使用UTF8编码,是我根据下面的现象猜测的,没看源代码。
1、通过pgAdmin3查看在服务器以UTF8编码存储的“汉字”
在查询窗口中执行show client_encoding;可见pgAdmin3的默认客户端编码为UNICODE(在pg中为UTF8的别名)。查询select * from test,能正常显示“汉字”。
重设客户端编码set client_encoding to 'GBK';后再查询,却无法显示“汉字”。
在客户端编码为GBK的psgl中能正常显示的“汉字“到客户端编码为GBK的pgAdmin3中却无法显示。这是由于pgAdmin3与psgl内部使用了不同的编码方式所造成的:
应用程序psgl使用与pg客户端一样的编码方式,对从操作系统所得到的字符直接传给pg客户端,对从pg客户端所得到的字符直接传给操作系统显示。
应用程序pgAdmin3内部可能统一使用的是UTF8编码,对从操作系统所得到的字符(ANSI本地编码)要先转成UTF8编码后再传给pg客户端;对从pg客户端所得到的字符要先转成ANSI本地编码后再传给操作系统显示。
对于pgAdmin3 client_encoding = 'GBK' 时,“汉字“转换流程: UTF8 ->GBK->GBK;
pgAdmin3把本来是转后GBK编码的字符又当成UTF8进行转换,所以无法显示(转后没有对应的字符)。
对于pgAdmin3 client_encoding = 'UTF8' 时,“汉字“转换流程:UTF8 -> GBK;
此时客户端与服务端编码一样,不用转,直接将得到的字符转成GBK,所以能正常显示。
2、在client_encoding = ‘GBK’ 环境下,插入“汉字G“
此时pgAdmin3把ANSI编码的“汉字G“转成UTF8编码给客户端,因为客户端编码为GBK和服务端编码不一样,所以数据库又将其作为GBK编码转成UTF8编码进行存储。本来就已经是UTF8编码的字符又作为GBK编码转成UTF8,存储字符就是错的了。但查询时却能正常显示,因为在此环境逆转换的字符还是正确的。
3、在client_encoding = ‘UTF8’ 环境下,插入“汉字U“
此时pgAdmin3把ANSI编码的“汉字G“转成UTF8编码给客户端,因为客户端编码为UTF8和服务端编码一样,不进行任何转换直接存储。查询时在此环境下逆转换后也是正确的,因此也能正常显示。
总结:
1、pgAdmin3内部使用UTF8编码,并将pg客户端也设为UTF8编码,如果服务端也设为UTF8时,pgAdmin3就比较强大了,可以支持各国语言,存取各国文字,就没有国际化问题了。并且在存取时只用在本地的ANSI编码和UTF8编码之间转换一次即可。
2、应用程序内部应尽量使用与数据库客户端相同的编码(或传给客户端的字符编码与客户端编码相同),以保证存到库里的字符是正确的;数据库客户端与服务端编码如不一样,数据库自身会自动转换后存储。
验证pgAdmin3内部使用UTF8编码:用encode查看字符在数据库的存储字节
set client_encoding to 'UTF8';
select encode('汉字','hex') from test;
输出:"e6b189e5ad97" 为“汉字”的UTF-8编码。
set client_encoding to 'GBK';
select encode('汉字','hex') from test;
输出:" "e5a7b9e5a48ae793a7" 为将"e6b189e5ad97"作为GBK编码转换为UTF-8后的编码。
详细可参考其官方文档 http://www.postgresql.org/docs/9.2/interactive/multibyte.html 。支持简体中文有四种编码:EUC_CN(Extended UNIX Code-CN)、GB18030、GBK和UTF-8。但GB18030和GBK只能作为客户端编码,不能设置为服务端编码;由于Windows上又不支持EUC_CN编码,所以在Windows上服务端编码只能设为UTF-8。
下面通过两个简单的示例,来说明其编码转换过程。
数据:表test,字段name,类型text
示例一 客户端编码和服务端编码之间的转换(使用psgl)
1、服务端编码为UTF-8,客户端工具psgl默认为GBK
![]() |
2、在此环境下插入“汉字”,一切正常。此时传到客户的“汉字”为GBK编码,自动转为UTF-8编码存到服务端;而查询时,又自动将服务端的UTF-8编码转为GBK来显示,所以没有出现乱码。
![]() |
3、将客户端编码设置为UTF-8,则刚才插入的“汉字”不能正常显示。因为此时客户端和服务端的编码一样,在取数据时不进行任何转换,直接将存在服务端的UTF8编码的字节传到客户端,之后psgl直接显示,所以就乱码了。
![]() |
4、在此环境下插入“汉字”,则添加不成功,因为“汉字”直接以GBK的形式传到服务端,UTF8编码不认识,所以就报错。(现在客户端编码为UTF8,所以提示的中文信息也乱码了)。
总结:1、在此示例中,应用程序psgl,对所输入和获取的字符没做任何处理,直接显示,其使用了pg客户端一样的编码方式(GBK)。
2、在使用时尽量保证客户端编码和操作系统环境一致,不然显示和添加就会出现乱码情况。
示例二 应用程序、客户端和服务端编码转换(pgAdmin3可视化界面)
pgAdmin3内部使用UTF8编码,是我根据下面的现象猜测的,没看源代码。
1、通过pgAdmin3查看在服务器以UTF8编码存储的“汉字”
在查询窗口中执行show client_encoding;可见pgAdmin3的默认客户端编码为UNICODE(在pg中为UTF8的别名)。查询select * from test,能正常显示“汉字”。
重设客户端编码set client_encoding to 'GBK';后再查询,却无法显示“汉字”。
在客户端编码为GBK的psgl中能正常显示的“汉字“到客户端编码为GBK的pgAdmin3中却无法显示。这是由于pgAdmin3与psgl内部使用了不同的编码方式所造成的:
应用程序psgl使用与pg客户端一样的编码方式,对从操作系统所得到的字符直接传给pg客户端,对从pg客户端所得到的字符直接传给操作系统显示。
应用程序pgAdmin3内部可能统一使用的是UTF8编码,对从操作系统所得到的字符(ANSI本地编码)要先转成UTF8编码后再传给pg客户端;对从pg客户端所得到的字符要先转成ANSI本地编码后再传给操作系统显示。
对于pgAdmin3 client_encoding = 'GBK' 时,“汉字“转换流程: UTF8 ->GBK->GBK;
pgAdmin3把本来是转后GBK编码的字符又当成UTF8进行转换,所以无法显示(转后没有对应的字符)。
对于pgAdmin3 client_encoding = 'UTF8' 时,“汉字“转换流程:UTF8 -> GBK;
此时客户端与服务端编码一样,不用转,直接将得到的字符转成GBK,所以能正常显示。
2、在client_encoding = ‘GBK’ 环境下,插入“汉字G“
此时pgAdmin3把ANSI编码的“汉字G“转成UTF8编码给客户端,因为客户端编码为GBK和服务端编码不一样,所以数据库又将其作为GBK编码转成UTF8编码进行存储。本来就已经是UTF8编码的字符又作为GBK编码转成UTF8,存储字符就是错的了。但查询时却能正常显示,因为在此环境逆转换的字符还是正确的。
3、在client_encoding = ‘UTF8’ 环境下,插入“汉字U“
此时pgAdmin3把ANSI编码的“汉字G“转成UTF8编码给客户端,因为客户端编码为UTF8和服务端编码一样,不进行任何转换直接存储。查询时在此环境下逆转换后也是正确的,因此也能正常显示。
总结:
1、pgAdmin3内部使用UTF8编码,并将pg客户端也设为UTF8编码,如果服务端也设为UTF8时,pgAdmin3就比较强大了,可以支持各国语言,存取各国文字,就没有国际化问题了。并且在存取时只用在本地的ANSI编码和UTF8编码之间转换一次即可。
2、应用程序内部应尽量使用与数据库客户端相同的编码(或传给客户端的字符编码与客户端编码相同),以保证存到库里的字符是正确的;数据库客户端与服务端编码如不一样,数据库自身会自动转换后存储。
验证pgAdmin3内部使用UTF8编码:用encode查看字符在数据库的存储字节
set client_encoding to 'UTF8';
select encode('汉字','hex') from test;
输出:"e6b189e5ad97" 为“汉字”的UTF-8编码。
set client_encoding to 'GBK';
select encode('汉字','hex') from test;
输出:" "e5a7b9e5a48ae793a7" 为将"e6b189e5ad97"作为GBK编码转换为UTF-8后的编码。