由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 从应用程序角度来看,如果要将数据从来源取出,可以使用输入 ...
随机推荐
- CodeForces - 220B Little Elephant and Array (莫队+离散化 / 离线树状数组)
题意:N个数,M个查询,求[Li,Ri]区间内出现次数等于其数值大小的数的个数. 分析:用莫队处理离线问题是一种解决方案.但ai的范围可达到1e9,所以需要离散化预处理.每次区间向外扩的更新的过程中, ...
- oracle 数据泵
Oracle数据库导入导出工具,可以使用exp/imp,但这是比较早期的工具.本文主要介绍数据泵expdp/impdp工具的使用. 1.建立数据泵目录 使用数据泵需要先建directory c ...
- Linux系统启动管理 系统启动流程
概述 linux启动时我们会看到许多启动信息,其过程可以分为5个阶段: BIOS自检 读取MBR 通过Boot Loader引导系统加载 加载initramfe虚拟文件系统 加载内核 运行system ...
- sql 语句 名称解析,是 由内向外的。
子查询内 找不到的 字段 会 向外 寻找,还是找不到 就报错:找到了就不报错,但是 子查询语句就毫无意义了: 解决办法: 字段前面要跟上表的名称. 一般 字段无效 立刻 报错.
- jQuery图片垂直滚动焦点图
在线演示 本地下载
- InterruptedException异常
本文总结自:https://blog.csdn.net/asdfsadfasdfsa/article/details/78808131 什么样的方法会抛出InterruptedException异常? ...
- maven中使用dom4j解析、生成XML的简易方法
此片文章主要写一些关于如何在maven工程中使用dom4j来解析或生成XML的建议方法,实际可使用的写法不仅限于如下所写的样例代码.此处进攻快速入手和提供思路使用. 首先配置pom.xml中的依赖的包 ...
- dotnet new vue [C# 使用 vuejs]
1. 安装 dotnet sdk 2.0 2. 安装 nodejs , npm 3. 安装淘宝镜像 4. 更新npm : npm update -g 5. dotnet new -i vue 6. ...
- spring security使用数据库验证的逻辑处理
前面做了多个示例,包括使用jdbc和hibernate两种方式访问数据库获取用户信息和权限信息,其中一些关键步骤如下: 我们在SecurityConfig中配置覆盖configure方法时候,可以 ...
- Merge-Sort(归并排序)
Merge-Sort(归并排序) 思想 利用分治的思想,具体实现也就是递归,不断的将问题话分为更小的子问题,当子问题中规模为1的时候,认为数组已经有序了,然后再将子问题求得的结果不断的合并.也就是将长 ...