1.区域支持概述
区域支持是指应用遵守文化偏好的问题,包括字母表、排序、数字格式等
PG使用服务器操作系统提供的标准 ISO C 和POSIX的区域机制
默认情况下,initdb将会按照它的执行环境的区域设置初始化数据库集簇
PG区域支持是在使用initdb创建一个数据库集簇时自动被初始化的可以选择initdb数据库集群时指定区域属性
initdb -D $PGDATA -E UTF8 --locale=C
2.区域
由于国家和本地习惯的不同,在处理文字、日期、数字、货币格式等问题 都会有所不同,
计算机中“区域(locale)”就是用来解决这个问题的。
区域名的形式
language_territory[.codeset]
特殊的区域(C或者POSIX)
locale "C"或"POSIX"是一个可移植的语言环境
它的 LC_CTYPE 部分对应于7位ASCII字符集
[pgsql@postgresql:/postgresql/pgdata]$locale
LANG=en_US.UTF8
LC_CTYPE="en_US.UTF8"
LC_NUMERIC="en_US.UTF8"
LC_TIME="en_US.UTF8"
LC_COLLATE="en_US.UTF8"
LC_MONETARY="en_US.UTF8"
LC_MESSAGES="en_US.UTF8"
LC_PAPER="en_US.UTF8"
LC_NAME="en_US.UTF8"
LC_ADDRESS="en_US.UTF8"
LC_TELEPHONE="en_US.UTF8"
LC_MEASUREMENT="en_US.UTF8"
LC_IDENTIFICATION="en_US.UTF8"
LC_ALL=
区域的类别属性。
LC_COLLATE:字符排序顺序
LC_CTYPE:字符分类(什么是字母,是否区分大小写)
LC_MESSAGES:消息的语言
LC_MONETARY:货币金额的格式
LC_NUMERIC:数值格式
LC_TIME:日期和时间格式。
3.OS区域设置:
Linux:
通过环境变量(LC_ALL/LC_*/LANG)设置
本地语言的支持依赖于/etc/locale.conf
[pgsql@postgresql:/postgresql/pgdata]$cat /etc/locale.conf
LANG="zh_CN.UTF-8"
环境变量的优先级
LC_ALL > LC_* > LANG
其它相关指令
locale #查看当前系统环境的区域设置
locale –a #获得Glibc 支持的本地字符集
[pgsql@postgresql:/postgresql/pgdata]$locale -a
...........(省略很多)
zh_CN
zh_CN.gb18030
zh_CN.gb2312
zh_CN.gbk
zh_CN.utf8
zh_TW.utf8
4.区域配置的影响
集群服务:postgresq.conf
client_encoding:客户端编码:影响:C/S间字符编码转换。
lc_messages:消息的语言:影响:错误消息的语言
lc_monetary/lc_numeric/lc_time/DateStyle:货币,数值和时间的显示格式:
影响:货币,数值和日期类型数据的输出格式to_char函数族。
数据库:pg_database
项目:说明:影响
encoding:数据库编码:postgres进程和数据文件的字符编码
Collate:字符排序顺序:字符比较,ORDER BY,字符列的索引使用。
Ctype:字符分类(什么是字母,是否区分大小写):upper,lower,initcap大小写不敏感
的模式和使用了字符分类的正则表达式匹配
postgresql.conf 区域参数
主要包括以下属性
show client_encoding;
show lc_messages ;
show lc_monetary ;
show lc_numeric ;
show lc_time ;
show DateStyle ;
show default_text_search_config;
postgres=# show client_encoding;
client_encoding
-----------------
UTF8
postgres=# show lc_messages ;
lc_messages
-------------
zh_CN.UTF-8
postgres=# show lc_monetary ;
lc_monetary
-------------
C
postgres=# show lc_numeric ;
lc_numeric
------------
C
postgres=# show lc_time ;
lc_time
---------
C
postgres=# show DateStyle ;
DateStyle
-----------
ISO,MDY
postgres=# show default_text_search_config;
default_text_search_config
----------------------------
pg_catalog.simple
(1 row)
5.区域参数修改
通过SHOW命令或系统表pg_settings查看
通过set命令修改当前会话的参数
通过alter system ;pg_ctl reload 命令在线全局变更
postgres=# show lc_messages;
lc_messages
-------------
(1 row)
postgres=# set lc_messages='zh_CN.UTF-8';
SET
postgres=# show lc_messages;
lc_messages
-------------
zh_CN.UTF-8
(1 row)
PG数据库固有区域属性
包括以下三种属性,数据库创建后不可变更
Encoding:字符编码。
Collate:排序字符集
Ctype:字符分类
可通过psql的”\l”或系统表pg_database查看
postgres=# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+----------+----------+------------+------------+-----------------------
itpuxdb | itpux | UTF8 | en_US.utf8 | en_US.utf8 |
postgres | postgres | UTF8 | en_US.utf8 | en_US.utf8 |
sjztdb | postgres | UTF8 | en_US.utf8 | en_US.utf8 |
template0 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres+ postgres=CTc/postgres
template1 | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =c/postgres+ postgres=CTc/postgres
testdb2 | postgres | UTF8 | en_US.utf8 | en_US.utf8 |
(6 rows)
postgres=# select * from pg_database;
oid | datname | datdba | encoding | datcollate | datctype | datistemplate | datallowconn | datconnlimit | datlastsysoid | datfrozenxid | datminmxid | dattablespace | datacl
-------+-----------+--------+----------+------------+------------+---------------+--------------+--------------+---------------+--------------+------------+---------------+-------------------------------------
13593 | postgres | 10 | 6 | en_US.utf8 | en_US.utf8 | f | t | -1 | 13592 | 479 | 1 | 1663 |
16385 | itpuxdb | 16384 | 6 | en_US.utf8 | en_US.utf8 | f | t | -1 | 13592 | 479 | 1 | 1663 |
1 | template1 | 10 | 6 | en_US.utf8 | en_US.utf8 | t | t | -1 | 13592 | 479 | 1 | 1663 | {=c/postgres,postgres=CTc/postgres}
13592 | template0 | 10 | 6 | en_US.utf8 | en_US.utf8 | t | f | -1 | 13592 | 479 | 1 | 1663 | {=c/postgres,postgres=CTc/postgres}
16403 | sjztdb | 10 | 6 | en_US.utf8 | en_US.utf8 | f | t | -1 | 13592 | 479 | 1 | 1663 |
16407 | testdb2 | 10 | 6 | en_US.utf8 | en_US.utf8 | f | t | -1 | 13592 | 479 | 1 | 1663 |
(6 rows)
6.创建集群和创建数据库时字符集设置
initdb集群服务时区区域设置
如未明确指定区域和编码,initdb通过OS运行环境判断区域和编码
initdb时可通过参数指定数据库集群的缺省区域和编码
创建数据库时区域设置
创建数据库时默认继承数据库模板template1的区域设置
Encoding
Collate
Ctype
字符编码,LC_COLLATE和LC_CTYPE在数据库创建后不能变更
也可以指定其它的区域设置(必须使用template0作为模板)
create database newdb
template=template0
encoding='UTF8'
lc_collate='zh_CN.utf8'
lc_ctype='zh_CN.utf8';
7.乱码问题
字符编码和乱码
字符编码
字符编码是字符在计算机中以二进制值表示的方法,比如'a'的ACSII码是0x61
支持简体中文的字符编码包括: UTF8,GB2312(EUC_CN),GBK,GB18030
乱码
字符编码解码的过程中出现错误就会产生乱码
出现乱码可从以下几个方面找原因:
显示的字体和字符编码
处理过程中的编码转换
数据的源头是否有非法字符
PG支持的中文字符编码
服务端支持的简体中文字符编码
UTF8,EUC_CN
客户端支持的简体中文字符编码
UTF8,EUC_CN,GB18030
PostgreSQL使用的flex按照ASCII编码解析SQL语句,
ASCII不兼容的编码会让PostgreSQL头疼
为什么服务端不支持GBK和GB18030?
编码:编码范围:备注
utf8:单字节:00-7F(ASCII)/多字节:80-XX:ASCII兼容
EUC_CN(GB2312):双字节:A1-F7,A1-FE:ASCII兼容
GBK:双字节:81-FE,40-7E/80-FE:ASCII不兼容
GB18030:单字节:00-7F(ASCII)/双字节:81-FE,40-7E/80FE/四字节:81-FE,30-39,81-FE,30-39:ASCII不兼容。
数据库编码问题
涉及以下三个方面
数据库服务器编码
数据库客户端编码
本地环境编码
数据库服务器编码
指数据库服务器能够从客户端接收、存储以及向客户端提供该种编码的字符,并能将该种编码的字符转换到其它编码
查看PostgreSQL数据库服务器端编码:
postgres=# show server_encoding;
server_encoding
-----------------
UTF8
(1 row)
postgres=# \l
数据库客户端编码
客户端工具支持某种编码,必须能够显示从数据库读取的该种编码的字符,也能通过本工具将该种编码的字符提交到给服务器端。
查看PostgreSQL客户端工具psql编码
postgres=# show client_encoding;
postgres=# \encoding
UTF8
指定Postgresql会话的客户端编码:
postgres=# set client_encoding to 'utf8';
本地环境编码
如果使用dos的命令行界面,本地环境就是指dos命令行环境的编码
可以使用dos命令chcp查看dos环境编码:
C:\Users\4201.HJSC>chcp
活动代码页: 936
----936为简体中文,GBK;
如果在使用某种编辑器,则本地环境编码取该编辑器的编码设置
C/S自动字符编码转换
C/S间编码不一致时服务端自动进行字符编码转换
遵从一个原则:本地环境的编码和客户端编码需一致
客户端通过client_encoding通知服务端自己的编码
设置client_encoding到的几种方式(越往下优先级越高)
postgresql.conf
连接包(StartupMessage)的参数
set client_encoding to 'XXX';
8.编码注意事项
服务端使用UTF8作为数据库编码
SQL_ASCII缺少编码检查
EUC_CN的字符不够多,并且PostgreSQL没有定义EUC_CN和GBK/GB18030间的默认转码函数
客户端通过client_encoding通知服务端自己的编码
psql等工具能根据环境自动设置合适的client_encoding,执行psql前需要设置合适的区域环境
使用libpq编程时需注意client_encoding的设置
编码建议
服务端使用UTF8作为数据库编码
客户端设置合适的区域环境和client_encoding
数据库的Collate设成C
然后只在真正需要按拼音排序的列或者表达式上使用Collate“zh_CN”。
使用标准的区域无关的数据输出格式
1)创建数据库集群
initdb -E UTF8 --locale=C data
2)启动数据库:
export LC_ALL=zh_CN.UTF8
pg_ctl -D data -l logfile start
3)客户端建立连接:
export LC_ALL=zh_CN.UTF8
psql
原文地址:https://blog.csdn.net/weixin_43346403/article/details/129769741
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。