由PostgreSQL的区域与字符集说起(转)
转自:http://blog.chinaunix.net/uid-354915-id-3502551.html
一、PostgreSQL的区域
区域属性有以下几个:
LC_COLLATE:字符串排序顺序
LC_CTYPE:字符分类(什么是字母?它是这个字母的等效大写?)
LC_MESSAGES:信息的语言
LC_MONETARY:货币金额的格式
LC_NUMERIC:数字的格式
LC_TIME:日期和时间的格式
PostgreSQL 使用服务器操作系统提供的标准 ISO C 和 POSIX 区域机制。
区域支持是在使用 initdb 创建一个数据库集群的时候自动初始化的。
如果你的OS已经设置为你的数据库集群想要的区域,那么你就什么也不用干了。
如果你想要你的系统表现得像没有区域支持一样,那么使用特殊的区域 C 或 POSIX
一些区域性质的值一旦运行了 initdb 之后,你就再也不能更改它们了。LC_COLLATE 和 LC_CTYPE 就是这样的。它们影响索引的排序顺序,因此它们必需保持固定,其它区域性质可以在服务器启动的时候根据需要通过配置postgresql.conf变量来改变,如果你在 postgresql.conf 里面删除了这些缺省值,那么服务器将会继承来自运行环境的设置。
我们谈到从执行环境继承区域的时候,比如字符集,按照下面的顺序评估这些环境变量,直到找到一个已设置的:LC_ALL, LC_COLLATE, LANG 。如果这些环境变量一个都没有设置,那么区域缺省为 C 。一些信息区域化库也使用环境变量 LANGUAGE。
请检查核实 PostgreSQL 确实使用了你认为它该用的区域设置。LC_COLLATE 和 LC_CTYPE 的设置都是在 initdb 时决定的,如果不重复 initdb 是不可能改变的。其它的区域设置包括 LC_MESSAGES 和 LC_MONETARY 都是由服务器的启动环境决定的,但是可以在运行时修改。你可以用 SHOW 命令检查数据库正在使用的区域设置。
二、PostgreSQL的字符集
缺省的字符集是在使用 initdb 初始化数据库集群的时候选择的。在你创建数据库的时候是可以覆盖这个缺省的。因此,你可以为多个数据库设置不同的字符集。
虽然你可以给一个数据库声明你需要的任何编码,但选择一个与你选择的区域不一致的编码还是不妥的做法。LC_COLLATE 和 LC_CTYPE 设置暗示一个特定的编码,与区域相关的操作(比如排序)在不兼容的编码里很有可能产生错误的解析。
一个安全使用多种编码的方法是在 initdb 的时候把区域设置为 C 或 POSIX ,这样就关闭了任何实际的区域敏感性。
PostgreSQL 支持在服务器和前端之间的自动编码转换。
假如无法进行特定的字符转换,比如,你选的服务器编码是 EUC_JP 而客户端是 LATIN1 ,那么有些日文字符不能转换成 LATIN1 。这时将报告错误。
三、扩展:
1、常见编码及转换
UTF8 = UNICODE8;
UNICODE16是我们经常说的UNICODE;
GBK即汉字内码扩展规范,GBK是ANSI的一种,用0x80~0xFF 范围的2个字节来表示1个字符,根据微软资料,GBK是对GB2312-80的扩展,也就是CP936字码表;
windows英文版默认的应该是windows1252;
windows中文版用的是GB2312/GBK(用dos命令chcp查看,936为简体中文);
liunx很多默认编码都是utf-8,但是你可以通过命令设置成GB2312;
网页编码,通常是跟编辑网页的编辑器有关,比如说你的编辑器设置为GB2312字符集,那么你的网页的编码就是GB2312的。如果你用英文的操作系统打开就会是乱码。不过现在的浏览器都支持字符集识别,它会帮你把GB2312编码的网页自动转换为unicode的网页,从而解决乱码的问题。
如果你的文件编码是GBK,而你的系统环境是windows1252英文环境,那么这时候你打开文件就会是乱码的;
解决方案有两种:
(1)改变系统的语言为中文就可以解决乱码的问题;
(2)将GBK编码的文件转换为unicode编码,unicode编码是万国码,一般的操作系统都支持,不存在打开后乱码的问题。
每种编码都有自己的二进制编码集,平时经常遇到的问题是:
(1)对字符进行了错误的编码解析,导致出现乱码;
(2)字符在两个字符集中都存在,导致这部分字符变成“?”。
2、数据库编程的编码问题
数据库编程设计的编码问题包括三个方面:
数据库服务器编码;
数据库客户端编码;
本地环境编码。
(1)数据库服务器字符编码:
数据库服务器支持某种编码,是指数据库服务器能够从客户端接收、存储以及向客户端提供该种编码的字符,并能将该种编码的字符转换到其它编码。
查看PostgreSQL数据库服务器端编码:
postgres=# show server_encoding;
server_encoding
-----------------
UTF8
postgres=# \l
名称 | 拥有者 | 字元编码 | Collate | Ctype | TestDb1 | TestRole1 | UTF8 | Chinese (Simplified)_People's Republic of China.936 | Chinese (Simplified)_People's Republic of China.936 |
TestDb2 | postgres | UTF8 | Chinese (Simplified)_People's Republic of China.936 | Chinese (Simplified)_People's Republic of China.936 |
postgres | postgres | UTF8 | Chinese (Simplified)_People's Republic of China.936 | Chinese (Simplified)_People's Republic of China.936 |
template0 | postgres | UTF8 | Chinese (Simplified)_People's Republic of China.936 | Chinese (Simplified)_People's Republic of China.936 |
(2)数据库客户端字符编码:
客户端工具支持某种编码,必须能够显示从数据库读取的该种编码的字符,也能通过本工具将该种编码的字符提交到给服务器端。
查看PostgreSQL客户端工具psql编码:
postgres=# show client_encoding;
GBK
postgres=# \encoding
GBK
指定Postgresql会话的客户端编码:
postgres=# set client_encoding to 'utf8';
SET
postgres=# show client_encoding;
client_encoding
-----------------
UTF8
(3)本地环境编码:
如果使用dos的命令行界面,本地环境就是指dos命令行环境的编码,可以使用dos命令chcp查看dos环境编码:
D:\Program Files\PowerCmd>chcp
活动代码页: 936
----936为简体中文,GBK;
如果在使用某种编辑器,则本地环境编码取该编辑器的编码设置。
四、实例
虽然PG支持客户端和服务器端的编码自动转换,但是还需要遵从一个原则:本地环境的编码和客户端编码需一致。
1、PostgreSQL的数据库postgres,服务器端字符编码为utf8,客户端工具psql字符编码为GBK,本地环境dos命令编辑器编码为GBK,此时:
postgres=# show server_encoding;
server_encoding
-----------------
UTF8
(1 行记录)
postgres=# show client_encoding;
client_encoding
-----------------
GBK
(1 行记录)
postgres=# \! chcp
活动代码页: 936
postgres=# select * from "TestTb1";
Column1
-----------
测试
11
由于本地环境和客户端编码都是GBK,一致,没有问题;
insert时,客户端接收本地环境输入的GBK字符(两者都为GBK),客户端传到服务器端时自动转换为UTF-8编码存储,没有问题;
select时,服务器端传到客户端,UTF-8编码自动转换为GBK编码,在本地环境显示时,本地环境就是GBK编码,显示没有问题。
2、PostgreSQL的数据库postgres,服务器端字符编码为utf8,客户端工具psql字符编码为utf8,本地环境dos命令编辑器编码为GBK,此时:
postgres=# set client_encoding to 'utf8';
SET
postgres=# insert into test values('测试1');
閿欒?: 鏃犳晥鐨?"UTF8" 缂栫爜瀛楄妭椤哄簭: 0xb2
postgres=# select * from test;
column1
--------------------
娴嬭瘯
(1 行记录)
由于客户端和服务器的编码一致,故不进行转码,
insert时,本地输入的GBK编码到客户端不自动转换,客户端把接收的字符作为utf编码传给服务器端不转换,GBK的编码作为UTF-8存储,故有问题。
报错的信息为:ERROR: invalid byte sequence for encoding "UTF8": 0xb2;
select时,服务端的utf编码传给客户端不转换,客户端把utf编码传给本地环境不自动转换,utf8编码用gbk编码显示,故有问题。
3、本地环境就是指此时使用的环境,起初我使用powercmd代替windows的cmd命令行工具,实现上面第1个实例是总是失败(乱码)。
原因就是,此时本地环境编码是指powercmd的编码,而不是执行chcp命令得到的编码。
而powercmd使用的编码究竟是什么,我也没有找到。
由PostgreSQL的区域与字符集说起(转)的更多相关文章
- PostgreSQL如何导入SJIS字符集的文件
磨砺技术珠矶,践行数据之道,追求卓越价值 回到上一级页面: PostgreSQL杂记页 回到顶级页面:PostgreSQL索引页 [作者 高健@博客园 luckyjackgao@gmail. ...
- pg_dump实例详解(备份postgresql和greenplum数据库)
一.pg_dump的用法:数据库的导入导出是最常用的功能之一,每种数据库都提供有这方面的工具,例如Oracle的exp/imp,Informix的dbexp/dbimp,MySQL的mysqldump ...
- postgresql数据库的数据导出
一.pg_dump的用法:数据库的导入导出是最常用的功能之一,每种数据库都提供有这方面的工具,例如Oracle的exp/imp,Informix的dbexp/dbimp,MySQL的mysqldump ...
- 初学者遇到的PostgreSQL字符集问题的解决
当初学者在使用PostgreSQL数据库,输入中文时,会遇到“ERROR: invalid byte sequence for encoding "UTF8": 0xd6d0”的 ...
- initdb - 创建一个新的 PostgreSQL数据库集群
SYNOPSIS initdb [ option...] --pgdata | -D directory DESCRIPTION 描述 initdb 创建一个新的 PostgreSQL 数据库集群. ...
- PostgreSQL编码格式:客户端服务器、客户端、服务器端相关影响
关于字符编码这块,官网链接: https://www.postgresql.org/docs/current/charset.html 刚刚写了几百字的东西因为断网,导致全没有了,重头再写,我就只想记 ...
- 通过源码安装PostgresSQL
通过源码安装PostgresSQL 1.1 下载源码包环境: Centos6.8 64位 yum -y install bison flex readline-devel zlib-devel yum ...
- Oracle Client安装与基本配置
1. 安装Oracle Client, 访问Oracle站点下载Oracle Database 11g Release 2 Client 或者(直接下载Oracle 11gR2 Client) 2. ...
- 20145215《Java程序设计》第6周学习总结
20145215<Java程序设计>第六周学习总结 教材学习内容总结 输入/输出 InputStream与OutputStream 从应用程序角度来看,如果要将数据从来源取出,可以使用输入 ...
随机推荐
- 解决 hybird 应用中重复获取 WebView,导致页面元素无法识别的问题
转载地址:http://blog.csdn.net/testman930/article/details/50799532 问题描述 在测APP的业务流,WebView和Native模式耦合在一起.例 ...
- 谷歌Project Fi服务(转)
问:谷歌推出的移动虚拟网络Project Fi到底是什么呀? 答:谷歌手里有很多张“牌”可以出,现在这家搜索巨头又将目标放在了无线产业.在美国,移动电信合约服务是AT&T, Verizon, ...
- [MongoDB] 学习笔记(2)
1. Mac 安装mongodb: 官网下载mac版mongodb,解压到本地目录,如/Applications/mongodb,注意这里的地址是根更目录下的Applications,然后在根目录下创 ...
- cdojQ - 昊昊爱运动 II
地址:http://acm.uestc.edu.cn/#/contest/show/95 题目: Q - 昊昊爱运动 II Time Limit: 3000/1000MS (Java/Others) ...
- LLServer--》对LevelDB的应用
http://code.google.com/p/llserver/ 查看libs path的路径 LD_DEBUG=libs /usr/bin/llserver -h
- Java中的静态方法是什么?
静态方法是使用公共内存空间的,就是说所有对象都可以直接引用,不需要创建对象再使用该方法. 例如,我创建一个类,里面有一个静态方法: class Test{ public static int z(in ...
- SpringBoot Lombok
简介 lombok是一个编译级别的插件,它可以在项目编译的时候生成一些代码.比如日常开发过程中需要生产大量的JavaBean文件,每个JavaBean都需要提供大量的get和set方法,如果字段较多且 ...
- code for 1 - 分治
2017-08-02 17:23:14 writer:pprp 题意:将n分解为n/2, n%2, n/2三部分,再将n/2分解..得到一个序列只有0和1,给出[l, r]问l到r有几个1 题解:分治 ...
- C++中map的用法
map的特性是,所有元素都会根据元素的减值自动被排序.map的所有元素都是pair,同时拥有实值(value)和键值(key).pair的第一个元素会被视为键值,第二个元素会被视为实值.map不允许两 ...
- vue-cli 一分钟搭建自己的vue项目
创建项目 1.安装全局vue-cli npm install vue-cli -g 2.生成项目模板(my_projuct为项目名称) vue init webpack my_projuct 3.进入 ...