PostgreSQLの文字セットサポートにより、ISO 8859シリーズなどのシングルバイト文字やEUC(拡張Unixコード)、UTF-8、Mule内部コードなどのマルチバイト文字を含む、各種文字セットでテキストを保存することができます。 全ての文字セットはクライアントにより透過的に使用することができますが、いくつかは、サーバ内での(つまりサーバサイドエンコーディングとして)使用はサポートされていません。デフォルトの文字セットは、initdbを使用したPostgreSQLデータベースクラスタの初期化時に決定されます。 これは、データベースを作成する時に上書きすることができるので、異なる文字セットを使用した複数のデータベースを持つことができます。
PostgreSQLで使用できる文字セットを表21-1に示します。
表 21-1. PostgreSQL文字セット
名前 | 説明 | 言語 | サーバ? | バイト数/文字 | 別名 |
---|---|---|---|---|---|
BIG5 | Big Five | 従来の中国語 | 1-2 | いいえ | WIN950、Windows950 |
EUC_CN | Extended UNIX Code-CN | 簡易中国語 | はい | 1-3 | |
EUC_JP | Extended UNIX Code-JP | 日本語 | はい | 1-3 | |
EUC_KR | Extended UNIX Code-KR | 韓国語 | はい | 1-3 | |
EUC_TW | Extended UNIX Code-TW | 従来の中国語、台湾語 | はい | 1-3 | |
GB18030 | National Standard | 中国語 | いいえ | 1-2 | |
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 | |
KOI8 | KOI8-R(U) | キリル語 | はい | 1 | KOI8R |
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 |
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の代わりに77encodingと書くこともできます。 -Eオプションも77encodingオプションも与えられない場合、initdbは、指定もしくはデフォルトのロケールに基づいて適当な符号化方式を決定しようとします。
異なる文字セットのデータベースを作成することができます。
createdb -E EUC_KR korean
これはEUC_KR文字セットでkoreanという名前のデータベースを作成します。 SQLコマンドで同じことを行うには次のようにします。
CREATE DATABASE korean WITH ENCODING 'EUC_KR';
データベースの符号化方式はpg_databaseシステムカタログに格納されます。 psqlの-lオプションか\lコマンドで符号化方式を確認することができます。
$ psql -l List of databases Database | Owner | Encoding ---------------+---------+--------------- euc_cn | t-ishii | EUC_CN euc_jp | t-ishii | EUC_JP euc_kr | t-ishii | EUC_KR euc_tw | t-ishii | EUC_TW mule_internal | t-ishii | MULE_INTERNAL postgres | t-ishii | EUC_JP regression | t-ishii | SQL_ASCII template1 | t-ishii | EUC_JP test | t-ishii | EUC_JP utf8 | t-ishii | UTF8 (9 rows)
重要項目: データベースに対して好みの符号化方式を任意に指定することができますが、選択したロケールが想定していない符号化方式を選択することはお勧めしません。 LC_COLLATE設定とLC_CTYPE設定は、暗黙的な特定の符号化方式を意味していますので、互換性のない符号化方式でロケールに依存した操作(ソート処理など)を行うと、データを間違って解釈してしまいます。
これらのロケール設定はinitdbで固定化されます。 1つのクラスタにおいて、異なるデータベースに異なる符号化方式を使用できるという、この見かけ上の柔軟性は現実的ではなく、理論に走ったものと言えます。 将来のバージョンのPostgreSQLで、これらの機構を変更する予定です。
安全に複数の符号化方式を使用する方法の1つとして、initdb時にロケールをCもしくはPOSIXに設定する方法があります。 これにより、ロケールを意識する必要がまったくなくなります。
PostgreSQLは、ある文字セットの組み合わせに対してサーバとクライアントの間で自動的に文字セットを変換する機能を提供しています。 変換情報はpg_conversionシステムカタログに格納されています。PostgreSQLには、表21-2で示されているように、事前に定義された変換が付属します。 新しい変換を作成するにはSQLコマンドのCREATE CONVERSIONを使用します。
表 21-2. クライアント・サーバ文字セット変換
サーバ文字セット | 利用可能なクライアント文字セット |
---|---|
BIG5 | サーバの符号化方式としてはサポートしていません。 |
EUC_CN | EUC_CN、 MULE_INTERNAL、 UTF8 |
EUC_JP | EUC_JP、 MULE_INTERNAL、 SJIS、 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 | JOHAB、 UTF8 |
KOI8 | KOI8、 ISO_8859_5、 MULE_INTERNAL、 UTF8、 WIN866、 WIN1251 |
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、 KOI8、 LATIN1 to LATIN4、 SJIS、 WIN866、 WIN1250、 WIN1251 |
SJIS | サーバの符号化方式としてはサポートしていません。 |
SQL_ASCII | どれでも (変換されません) |
UHC | サーバの符号化方式としてはサポートしていません。 |
UTF8 | すべてサポートされています。 |
WIN866 | WIN866、 ISO_8859_5、 KOI8、 MULE_INTERNAL、 UTF8、 WIN1251 |
WIN874 | WIN874、 UTF8 |
WIN1250 | WIN1250、 LATIN2、 MULE_INTERNAL、 UTF8 |
WIN1251 | WIN1251、 ISO_8859_5、 KOI8、 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関数を使います。
\encodingは結果を得るために実際はPQsetClientEncoding()
を呼び出しています。
int PQsetClientEncoding(PGconn *conn, const char *encoding);
ここでconnはサーバへの接続、encodingは使用したい符号化方式です。 この関数は符号化方式の設定に成功すると0を返し、失敗すると-1を返します。 この接続に対する現在の符号化方式は次のようにして確認できます。
int PQclientEncoding(const PGconn *conn);
EUC_JPのような記号文字列ではなく符号化方式IDを返すことに注意してください。 符号化方式IDを符号化方式名に変換するには次のようにします。
char *pg_encoding_to_char(int encoding_id);
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のデータを扱っている場合を除き、賢い方法ではありません。
ここに記したものは様々な符号化方式システムを学習するのに良い資料です。
An extensive collection of documents about character sets, encodings, and code pages.
3.2節にEUC_JP、EUC_CN、EUC_KR、EUC_TWの詳しい説明があります。
Unicode協会のWebサイトです。
ここでUTF-8が定義されています。