• postgresql编码问题


    基本使用参考 https://www.yiibai.com/postgresql/postgresql-insert.html 

    关于编码问题:

    这是一个很复杂,但弄懂之后还是很迷的问题。

    postgresql数据库编码问题主要体现在三个方面:

    一、数据库服务器字符集编码

    数据库服务器支持某种编码,是指数据库服务器能够从客户端接收、存储以及向客户端提供该种编码的字符,并能将该种编码的字符转换到其它编码。
    查看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使用的编码究竟是什么,我也没有找到。

    总结:①直接在psql执行insert或者select的时候,设置client_encoding=gbk(默认),不乱码;(上面例子证明了)

       ②使用“\i sql文件.sql”(sql文件是utf8编码)命令的时候,如果sql文件中有中文,一定要先行执行set client_encoding=utf8;(设置此之后,按照上面说的,客户端不转换,直接把接收的字符作为utf8编码传给服务器端,而文件本身就是utf8,所以不乱码;同理如果sql文件是ansi编码即gbk编码的话,确保client_encoding为gbk;总之,sql文件与client_encoding编码一致),才不乱码。

    还有一点需要注意,即如果使用pgAdmin可视化工具创建数据库的,需要知道自己传教数据库设置的collation是什么(默认是GBK),如果是这样的话就需要将传入的文件编码格式转换成gbk格式(ANSI也即是gbk编码)

    关于数据库查询以及其他操作缓慢的问题:

    数据执行过删除操作,产生碎片。

    执行reindex index id_pkey_2018_08_07;

    重建主键索引以后,查询恢复正常。

    重建索引会锁定表,无法写入数据,注意执行的时机。

  • 相关阅读:
    学习bootsect.s中经常会问到的问题
    c++资源之不完全导引(全文) (转载)
    bootsect.S (读核笔记系列)
    WAP开发FAQ
    学习使用groovy(翻译稿之第一章)
    "革命尚未成功,同志仍需努力!"
    JAVA中this用法小结(转)
    Android <Button>样式的设置方法
    最新SDK android开发环境搭建
    Android中的数据存取(一)Preference
  • 原文地址:https://www.cnblogs.com/holden1/p/9910691.html
Copyright © 2020-2023  润新知