基本使用參考 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;
重建主鍵索引以后,查詢恢復正常。
重建索引會鎖定表,無法寫入數據,注意執行的時機。