PostgreSQL 數據庫編碼


PostgreSQL 數據庫編碼問題

1. 數據庫不支持中文,如何使用utf-8編碼

解決辦法:

注意:以下所有代碼都應在數據庫中執行,即可以輸入 ‘\l’ 查看數據庫的命令行,其行首有 ’=#‘ (超級用戶) 或 ’=>‘ (普通用戶)。

方法一:直接修改數據庫編碼

# 修改 datname 為你的數據庫名字,兩條命令效果相同,選擇一個即可
update pg_database set encoding=6 where datname='postgres';
# 命令2
update pg_database set encoding=pg_char_to_encoding('UTF8') 
where datname='postgres';

方法二:修改模板庫編碼,一勞永逸。

# 修改模板庫template1編碼, 同理可修改 template0
update pg_database 
set (encoding, datctype, datcollate)=(6, 'en_US.UTF8','en_US.UTF8') 
where datname = 'template1';

方法三:創建/刪除模板庫

# 創建模板庫,這是一條命令,SQL語法允許命令分行,以分號結束,但回車后,前一行命令不可修改
# 復制前先將第一行的 template1 改成你想要的名字,比如任何簡單的名字: td 
create database template1 with 
template template0 
encoding='UTF8' 
lc_ctype='en_US.UTF8' 
lc_collate='en_US.UTF8' 
allow_connections=TRUE 
is_template=True;

# 以后創建數據庫指定模板創建即可
create database template mytemplate;

# 也可以一勞永逸,刪除原來的 template1, 重新創建即可
# 先將模板庫變成普通數據庫,使 datistemplate=True 可以將任何普通數據庫變成模板庫。
update pg_database set datistemplate=False where datname='template1';
# 刪除數據庫
drop database template1;

2. 深入理解

模板庫

PostgreSQL 安裝后自帶三個庫:template0,template1 和 postgres。

template 是模板的意思,template0,template1都是模板庫,創建數據庫便實質是拷貝模板庫,默認的模板庫是 template1。兩個模板庫的唯一區別就是 template1 是可連接的,而 template0 不可連接,就是 \c template 不能進入數據庫。這個屬性是可以修改的(見下文)。

postgres 是一個普通的數據庫,不能作為模板。這個屬性也是可以更改的(見下文),所以任何數據庫都能變成模板庫,模板庫唯一特點就是不能被刪除,所以要想刪除模板庫,需要先將模板庫變成普通數據庫。創建 postgres 數據庫唯一的目的便是方便進入數據庫,因為進入數據庫的命令psql的默認參數是psql -U 用戶名 -d 用戶名命名的數據庫 ,如psql -U postgres -d postgres, PostgreSQL 默認創建的用戶名為 postgres, 所以要創建一個名為postgres的數據庫。數據庫名是必要參數,如果沒有就進不了數據庫。

注意:創建數據庫必須依賴模板庫,所以不要刪除了全部的數據庫,否則沒有模板庫,就再也沒法創建數據庫了。

數據庫編碼

數據庫編碼都是可以直接修改的,所有數據庫基本參數都存放在表 pg_database 中,超級用戶可以在任何數據庫中查看它、修改它。

# 查看 pg_database 表結構,
\d pg_database
    Table "pg_catalog.pg_database"
    Column     |   Type    | Modifiers 
---------------+-----------+-----------
 datname       | name      | not null
 datdba        | oid       | not null
 encoding      | integer   | not null
 datcollate    | name      | not null
 datctype      | name      | not null
 datistemplate | boolean   | not null
 datallowconn  | boolean   | not null
 datconnlimit  | integer   | not null
 datlastsysoid | oid       | not null
 datfrozenxid  | xid       | not null
 datminmxid    | xid       | not null
 dattablespace | oid       | not null
 datacl        | aclitem[] | 
  • 參數說明

    • datname 數據庫名字, name類型即字符串,用單引號 ‘’ 括起來,如 ‘template1’。

    • encoding 數據庫編碼代號,一個整數。utf-8的代號為6,代號也可以通過函數得到:

      update pg_database set encoding=6 where ...
      update pg_database set encoding=pg_char_to_encoding('UTF8') where ...
      
    • datcollate、datctype 分別對應數據庫的 Collate 和 Ctype。name字符串,可為 ‘en_US.UTF-8’。模板庫的這兩個字段必須和encoding對應,否則創建數據庫時會報錯:

      ERROR:  encoding "UTF8" does not match locale "en_US"
      DETAIL:  The chosen LC_CTYPE setting requires encoding "LATIN1".
      
    • datistemplate 是否為模板庫, 布爾值: false/true ,不限大小寫: TRUE

    • datallowconn 是否能連接,布爾值。

查看表 pg_database 內容

select * from pg_database;
 datname  | datdba | encoding | datcollate |  datctype  | datistemplate | datallowconn | datconnlimit | datlastsysoid | datfrozenxid | datminmxid | dattablespace |               datacl                
----------+--------+----------+------------+------------+---------------+--------------+--------------+---------------+--------------+------------+---------------+-------------------------------------
postgres  |     10 |        6 | en_US      | en_US      | f             | t            |           -1 |         12416 |          662 |          1 |          1663 | 
template1 |     10 |        6 | en_US.UTF8 | en_US.UTF8 | t             | t            |           -1 |         12416 |          662 |          1 |          1663 | 
template0 |     10 |        6 | en_US.UTF8 | en_US.UTF8 | t             | f            |           -1 |         12416 |          662 |          1 |          1663 | {=c/postgres,postgres=CTc/postgres}
(3 rows)

修改表 pg_database / 修改數據庫編碼 / 修改模板庫編碼

這三個問題是等同的,都是用命令 update 修改表 pg_database

# 查看 update 命令用法
\h update 
Command:     UPDATE
Description: update rows of a table
Syntax:
[ WITH [ RECURSIVE ] with_query [, ...] ]
UPDATE [ ONLY ] table_name [ * ] [ [ AS ] alias ]
    SET { column_name = { expression | DEFAULT } |
          ( column_name [, ...] ) = ( { expression | DEFAULT } [, ...] ) |
          ( column_name [, ...] ) = ( sub-SELECT )
        } [, ...]
    [ FROM from_item [, ...] ]
    [ WHERE condition | WHERE CURRENT OF cursor_name ]
    [ RETURNING * | output_expression [ [ AS ] output_name ] [, ...] ]

這里只解釋兩種用法:

# 用法一:
update pg_database set datname='template1' where datname='mytemplate';
# 只能更改表的一個字段,例如這句修改數據庫的名字,只要將默認的模板刪了,就可以把自己的模板設置成默認模板了。

# 用法二:
update pg_database 
set (encoding, datcollate, datctype)=(6, 'en_US.UTF8','en_US.UTF8') 
where datname='template1';
# 更改表的多個字段,比如修改模板庫的編碼,需要同時修改三個字段。

創建數據庫時,也可以自定義某些參數,並不是完全復制模板庫,甚至可以直接創建模板庫。如下所示:

\h create database
Command:     CREATE DATABASE
Description: create a new database
Syntax:
CREATE DATABASE name
    [ [ WITH ] [ OWNER [=] user_name ]
           [ TEMPLATE [=] template ]
           [ ENCODING [=] encoding ]
           [ LC_COLLATE [=] lc_collate ]
           [ LC_CTYPE [=] lc_ctype ]
           [ TABLESPACE [=] tablespace_name ]
           [ ALLOW_CONNECTIONS [=] allowconn ]
           [ CONNECTION LIMIT [=] connlimit ]
           [ IS_TEMPLATE [=] istemplate ] ]

  • 解釋:
    • [] 里左邊的名字才是參數名,右邊的是說明,但 SQL 語句不區分大小寫,使用小寫字母更直觀,如 create database allow_connections true 。害怕寫錯單詞可以直接復制,使用大寫字母。
    • owner 擁有者,template 模板
    • encoding 編碼, lc_collate Collate屬性, lc_ctype Ctype屬性,這三個字段必須對應,設置時應同時設置。
    • allow_connection 允許連接,istemplate 是模板庫

如:創建一個模板庫

create database mytemplate 
encoding='UTF8' 
lc_ctype='en_US.UTF8' 
lc_collate='en_US.UTF8'
IS_TEMPLATE true
TEMPLATE template0;

敲重點:數據庫的三個有關編碼的字段 encoding、ctype、collate 必須同時設置,關系要對應,比如 ‘en_US.UTF-8’ 對應的編碼為 UTF8,代號6, 對應 ‘en_US’ 對應的編碼為 LATIN1,代號8 。 ‘en_US.UTF-8’ 雖為字符串,但一個字也不能錯。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM