PostgreSQLの文字セット(エンコーディングとも呼ばれます)サポートにより、ISO 8859シリーズなどのシングルバイト文字やEUC(拡張Unixコード)、UTF-8、Mule内部コードなどのマルチバイト文字を含む、各種文字セットでテキストを保存することができます。
全ての文字セットはクライアントにより透過的に使用することができますが、いくつかは、サーバ内での(つまりサーバサイドエンコーディングとして)使用はサポートされていません。デフォルトの文字セットは、initdbを使用したPostgreSQLデータベースクラスタの初期化時に決定されます。
これは、データベースを作成する時に上書きすることができるので、異なる文字セットを使用した複数のデータベースを持つことができます。
  
しかし重要な制限として、それぞれのデータベースの文字セットがサーバのLC_CTYPE(文字分類)およびLC_COLLATE(文字列並び替え順序)ロケール設定と互換性がなくてはいけないことがあげられます。
CもしくはPOSIXロケール設定の場合、どのような文字セットも許可されています。
しかし、libcが提供する他のロケール設定の場合、正しく動作する文字セットはひとつだけとなります。
(しかしWindowsではUTF-8符号化方式をどのロケールでも使用できます。)
ICUサポートが組み込まれている場合は、サーバサイドのすべてではないにしても、ほとんどのエンコーディングで、ICUが提供する照合順序が利用できます。
  
PostgreSQLで使用できる文字セットを表 23.1に示します。
表23.1 PostgreSQL文字セット
| 名前 | 説明 | 言語 | サーバ? | ICU? | バイト数/文字 | 別名 | 
|---|---|---|---|---|---|---|
| BIG5 | Big Five | 繁体字 | いいえ | いいえ | 1-2 | WIN950、Windows950 | 
| EUC_CN | Extended UNIX Code-CN | 簡体字 | はい | はい | 1-3 | |
| EUC_JP | Extended UNIX Code-JP | 日本語 | はい | はい | 1-3 | |
| EUC_JIS_2004 | Extended UNIX Code-JP, JIS X 0213 | 日本語 | はい | いいえ | 1-3 | |
| EUC_KR | Extended UNIX Code-KR | 韓国語 | はい | はい | 1-3 | |
| EUC_TW | Extended UNIX Code-TW | 繁体字、台湾語 | はい | はい | 1-3 | |
| GB18030 | National Standard | 中国語 | いいえ | いいえ | 1-4 | |
| GBK | Extended National Standard | 簡体字 | いいえ | いいえ | 1-2 | WIN936、Windows936 | 
| ISO_8859_5 | ISO 8859-5、ECMA 113 | ラテン/キリル | はい | はい | 1 | |
| ISO_8859_6 | ISO 8859-6、ECMA 114 | ラテン/アラビア語 | はい | はい | 1 | |
| ISO_8859_7 | ISO 8859-7、ECMA 118 | ラテン/ギリシャ語 | はい | はい | 1 | |
| ISO_8859_8 | ISO 8859-8、ECMA 121 | ラテン/ヘブライ語 | はい | はい | 1 | |
| JOHAB | JOHAB | 韓国語(ハングル) | いいえ | いいえ | 1-3 | |
| KOI8R | KOI8-R | キリル文字(ロシア) | はい | はい | 1 | KOI8 | 
| KOI8U | KOI8-U | キリル文字(ウクライナ) | はい | はい | 1 | |
| LATIN1 | ISO 8859-1、ECMA 94 | 西ヨーロッパ | はい | はい | 1 | ISO88591 | 
| LATIN2 | ISO 8859-2、ECMA 94 | 中央ヨーロッパ | はい | はい | 1 | ISO88592 | 
| LATIN3 | ISO 8859-3、ECMA 94 | 南ヨーロッパ | はい | はい | 1 | ISO88593 | 
| LATIN4 | ISO 8859-4、ECMA 94 | 北ヨーロッパ | はい | はい | 1 | ISO88594 | 
| LATIN5 | ISO 8859-9、ECMA 128 | トルコ | はい | はい | 1 | ISO88599 | 
| LATIN6 | ISO 8859-10、ECMA 144 | 北欧 | はい | はい | 1 | ISO885910 | 
| LATIN7 | ISO 8859-13 | バルト語派 | はい | はい | 1 | ISO885913 | 
| LATIN8 | ISO 8859-14 | ケルト | はい | はい | 1 | ISO885914 | 
| LATIN9 | ISO 8859-15 | LATIN1でヨーロッパと訛りを含む | はい | はい | 1 | ISO885915 | 
| LATIN10 | ISO 8859-16、ASRO SR 14111 | ルーマニア | はい | いいえ | 1 | ISO885916 | 
| MULE_INTERNAL | Mule内部コード | 多言語Emacs | はい | いいえ | 1-4 | |
| SJIS | Shift JIS | 日本語 | いいえ | いいえ | 1-2 | Mskanji、ShiftJIS、WIN932、Windows932 | 
| SHIFT_JIS_2004 | Shift JIS, JIS X 0213 | 日本語 | いいえ | いいえ | 1-2 | |
| SQL_ASCII | 未指定(テキストを参照) | 何でも | はい | いいえ | 1 | |
| UHC | 統合ハングルコード | 韓国語 | いいえ | いいえ | 1-2 | WIN949、Windows949 | 
| UTF8 | Unicode、8ビット | すべて | はい | はい | 1-4 | Unicode | 
| WIN866 | Windows CP866 | キリル文字 | はい | はい | 1 | ALT | 
| WIN874 | Windows CP874 | タイ語 | はい | いいえ | 1 | |
| WIN1250 | Windows CP1250 | 中央ヨーロッパ | はい | はい | 1 | |
| WIN1251 | Windows CP1251 | キリル文字 | はい | はい | 1 | WIN | 
| WIN1252 | Windows CP1252 | 西ヨーロッパ | はい | はい | 1 | |
| WIN1253 | Windows CP1253 | ギリシャ | はい | はい | 1 | |
| WIN1254 | Windows CP1254 | トルコ | はい | はい | 1 | |
| WIN1255 | Windows CP1255 | ヘブライ | はい | はい | 1 | |
| WIN1256 | Windows CP1256 | アラビア語 | はい | はい | 1 | |
| WIN1257 | Windows CP1257 | バルト語派 | はい | はい | 1 | |
| WIN1258 | Windows CP1258 | ベトナム語 | はい | はい | 1 | ABC、TCVN、TCVN5712、VSCII | 
全てのクライアントのAPIが上の一覧表に示した文字セットをサポートしているわけではありません。
例えばPostgreSQL JDBCドライバはMULE_INTERNAL、LATIN6、LATIN8、そしてLATIN10をサポートしません。
     
SQL_ASCIIの設定は、他の設定とかなり異なります。サーバのキャラクタセットがSQL_ASCIIのとき、サーバは0から127のバイト値をASCIIに変換します。一方、128から255までは変換されません。
設定がSQL_ASCIIの場合は、符号化は実行されません。よって、この設定は特定の符号化を使用している場合には、その符号化を無視するようになってしまいます。
多くの場合、ASCIIではない環境で作業する場合はSQL_ASCIIの設定を使用するのは、賢いことではありません。なぜならPostgreSQLはASCIIではない文字を変換したり検査したりすることは出来ないからです。
     
initdbでPostgreSQLクラスタのデフォルト文字セット(エンコーディング)を定義します。
以下に例を示します。
initdb -E EUC_JP
これはデフォルトの文字セットをEUC_JP(日本語拡張Unixコード)に設定します。
より長いオプションの文字列がお好みなら-Eの代わりに--encodingと書くこともできます。
-Eオプションも--encodingオプションも与えられない場合、initdbは、指定もしくはデフォルトのロケールに基づいて適当な符号化方式を決定しようとします。
    
データベース作成時に選択したロケールと互換性を持つ符号化方式を提供することで、デフォルト以外の符号化方式を指定することができます。
createdb -E EUC_KR -T template0 --lc-collate=ko_KR.euckr --lc-ctype=ko_KR.euckr korean
これはEUC_KR文字セットとko_KRロケールを使用するkoreanという名前のデータベースを作成します。
SQLコマンドで同じことを行うには次のようにします。
CREATE DATABASE korean WITH ENCODING 'EUC_KR' LC_COLLATE='ko_KR.euckr' LC_CTYPE='ko_KR.euckr' TEMPLATE=template0;
上のコマンドにてtemplate0データベースのコピーが指定されていることに注目してください。
他のデータベースからコピーする場合、データが破損する結果となる可能性がありますので、符号化方式とロケール設定を元のデータベースの設定から変更することはできません。
詳細については22.3を参照してください。
    
データベースの符号化方式はpg_databaseシステムカタログに格納されます。
psqlの-lオプションか\lコマンドで符号化方式を確認することができます。
$ psql -l
                                         List of databases
   Name    |  Owner   | Encoding  |  Collation  |    Ctype    |          Access Privileges          
-----------+----------+-----------+-------------+-------------+-------------------------------------
 clocaledb | hlinnaka | SQL_ASCII | C           | C           | 
 englishdb | hlinnaka | UTF8      | en_GB.UTF8  | en_GB.UTF8  | 
 japanese  | hlinnaka | UTF8      | ja_JP.UTF8  | ja_JP.UTF8  | 
 korean    | hlinnaka | EUC_KR    | ko_KR.euckr | ko_KR.euckr | 
 postgres  | hlinnaka | UTF8      | fi_FI.UTF8  | fi_FI.UTF8  | 
 template0 | hlinnaka | UTF8      | fi_FI.UTF8  | fi_FI.UTF8  | {=c/hlinnaka,hlinnaka=CTc/hlinnaka}
 template1 | hlinnaka | UTF8      | fi_FI.UTF8  | fi_FI.UTF8  | {=c/hlinnaka,hlinnaka=CTc/hlinnaka}
(7 rows)
最近のオペレーティングシステムでは、PostgreSQLは、LC_CTYPEの設定によりどの文字セットが指定されているか決定できます。
そして、一致するデータベース符号化方式のみを強制的に使用します。
古いオペレーティングシステムでは、自分で選択したロケールが想定している符号化方式を確実に使用することは各自の責任になります。
ここでの間違いは、ソート処理などのロケールに依存する操作が、奇妙な動作するといったことにつながります。
     
      PostgreSQLは、LC_CTYPEがCもしくはPOSIXでもない場合にも、スーパーユーザがSQL_ASCIIエンコーディングでデータベースを作成することを許可します。上記のように、SQL_ASCIIは、データベースに保存されているデータが特定のエンコーディングを持つことを強制しません。さらに、この選択はロケールに依存したおかしな動作を引き起こすリスクを高めます。この設定の組み合わせを使用することは、お勧めできませんし、いつの日か完全に禁止されるかもしれません。
     
PostgreSQLは、ある文字セットの組み合わせに対してサーバとクライアントの間で自動的に文字セットを変換する機能を提供しています。
変換情報はpg_conversionシステムカタログに格納されています。PostgreSQLには、表 23.2で示されているように、事前に定義された変換が付属します。
新しい変換を作成するにはSQLコマンドのCREATE CONVERSIONを使用します。
    
表23.2 クライアント・サーバ文字セット変換
| サーバ文字セット | 利用可能なクライアント文字セット | 
|---|---|
| BIG5 | サーバの符号化方式としてはサポートしていません。 | 
| EUC_CN | EUC_CN、 MULE_INTERNAL、UTF8 | 
| EUC_JP | EUC_JP、 MULE_INTERNAL、SJIS、UTF8 | 
| EUC_JIS_2004 | EUC_JIS_2004、 SHIFT_JIS_2004、UTF8 | 
| EUC_KR | EUC_KR、 MULE_INTERNAL、UTF8 | 
| EUC_TW | EUC_TW、 BIG5、MULE_INTERNAL、UTF8 | 
| GB18030 | サーバの符号化方式としてはサポートしていません。 | 
| GBK | サーバの符号化方式としてはサポートしていません。 | 
| ISO_8859_5 | ISO_8859_5、 KOI8、MULE_INTERNAL、UTF8、WIN866、WIN1251 | 
| ISO_8859_6 | ISO_8859_6、 UTF8 | 
| ISO_8859_7 | ISO_8859_7、 UTF8 | 
| ISO_8859_8 | ISO_8859_8、 UTF8 | 
| JOHAB | サーバの符号化方式としてはサポートしていません。 | 
| KOI8R | KOI8R、 ISO_8859_5、MULE_INTERNAL、UTF8、WIN866、WIN1251 | 
| KOI8U | KOI8U、 UTF8 | 
| LATIN1 | LATIN1、 MULE_INTERNAL、UTF8 | 
| LATIN2 | LATIN2、 MULE_INTERNAL、UTF8、WIN1250 | 
| LATIN3 | LATIN3、 MULE_INTERNAL、UTF8 | 
| LATIN4 | LATIN4、 MULE_INTERNAL、UTF8 | 
| LATIN5 | LATIN5、 UTF8 | 
| LATIN6 | LATIN6、 UTF8 | 
| LATIN7 | LATIN7、 UTF8 | 
| LATIN8 | LATIN8、 UTF8 | 
| LATIN9 | LATIN9、 UTF8 | 
| LATIN10 | LATIN10、 UTF8 | 
| MULE_INTERNAL | MULE_INTERNAL、 BIG5、EUC_CN、EUC_JP、EUC_KR、EUC_TW、ISO_8859_5、KOI8R、LATIN1からLATIN4まで、SJIS、WIN866、WIN1250、WIN1251 | 
| SJIS | サーバの符号化方式としてはサポートしていません。 | 
| SHIFT_JIS_2004 | サーバの符号化方式としてはサポートしていません。 | 
| SQL_ASCII | どれでも (変換されません) | 
| UHC | サーバの符号化方式としてはサポートしていません。 | 
| UTF8 | すべてサポートされています。 | 
| WIN866 | WIN866、 ISO_8859_5、KOI8R、MULE_INTERNAL、UTF8、WIN1251 | 
| WIN874 | WIN874、 UTF8 | 
| WIN1250 | WIN1250、 LATIN2、MULE_INTERNAL、UTF8 | 
| WIN1251 | WIN1251、 ISO_8859_5、KOI8R、MULE_INTERNAL、UTF8、WIN866 | 
| WIN1252 | WIN1252、 UTF8 | 
| WIN1253 | WIN1253、 UTF8 | 
| WIN1254 | WIN1254、 UTF8 | 
| WIN1255 | WIN1255、 UTF8 | 
| WIN1256 | WIN1256、 UTF8 | 
| WIN1257 | WIN1257、 UTF8 | 
| WIN1258 | WIN1258、 UTF8 | 
自動文字セット変換を有効にするためには、クライアントでどのような文字セット(符号化方式)を使用させたいかをPostgreSQLに伝えなければなりません。 これを行うにはいくつかの方法があります。
psqlで\encodingコマンドを使います。
\encodingは実行中であってもクライアントの符号化方式を変更させることができます。
例えば符号化方式をSJISに変えたい場合は次のように入力します。
\encoding SJIS
libpq (34.10)はクライアントの符号化方式を制御する関数を保持しています。
SET client_encoding TOを使います。
次のSQLコマンドでクライアントの符号化方式を設定できます。
SET CLIENT_ENCODING TO 'value';
標準SQLの構文SET NAMESを同じ目的で使うこともできます。
SET NAMES 'value';
現在のクライアントの符号化方式を問い合わせるには次のようにします。
SHOW client_encoding;
デフォルトの符号化方式に戻すのには次のようにします。
RESET client_encoding;
PGCLIENTENCODINGを使います。
クライアントの環境でPGCLIENTENCODING環境変数が定義されていると、サーバと接続が確立した時点で自動的にクライアントの符号化方式が選択されます
(上で説明したその他のどんな方法でもその後書き換えできます)。
       
client_encoding変数を使います。
client_encoding変数が設定されていると、サーバとの接続が確立した時点で自動的にクライアントの符号化方式が選択されます
(上で説明したその他のどんな方法でもその後書き換えできます)。
       
EUC_JPをサーバに、そしてLATIN1をクライアントに選んだ場合のように、
特定の文字の変換ができない時、日本語文字はLATIN1に入っていないという旨の日本語が返され、エラーが報告されます。
    
クライアント側のキャラクタセットがSQL_ASCIIに定義されている場合は、符号化変換はサーバ側のキャラクタセットに関係無く無効化されます。
サーバ側と同じように、SQL_ASCIIを使用することは、すべてASCIIのデータを扱っている場合を除き、賢い方法ではありません。
    
ここに記したものは様々な符号化方式システムを学習するのに良い資料です。
EUC_JP、EUC_CN、EUC_KR、EUC_TWの詳しい説明があります。
        
Unicode協会のWebサイトです。
ここでUTF-8(8ビットUCS/Unicode変換書式)が定義されています。