PostgreSQLの文字セット(エンコーディングとも呼ばれます)サポートにより、ISO 8859シリーズなどのシングルバイト文字やEUC(拡張Unixコード)、UTF-8、Mule内部コードなどのマルチバイト文字を含む、各種文字セットでテキストを保存することができます。 全ての文字セットはクライアントにより透過的に使用することができますが、いくつかは、サーバ内での(つまりサーバサイドエンコーディングとして)使用はサポートされていません。デフォルトの文字セットは、initdbを使用したPostgreSQLデータベースクラスタの初期化時に決定されます。 これは、データベースを作成する時に上書きすることができるので、異なる文字セットを使用した複数のデータベースを持つことができます。
しかし重要な制限は、それぞれのデータベースの文字セットがサーバのLC_CTYPE設定と互換性が無くてはいけません。 LC_CTYPEがCもしくはPOSIXのときは、どのような文字セットも許可されています。 しかし、他のLC_CTYPEの設定のときは、正しく動作する文字セットはひとつだけとなります。 LC_CTYPE設定がinitdbにより凍結されているため、(実際のロケール認識を無効化させる)C or POSIXロケールを選択したときを除いては、クラスタの異なるデータベースで用いられる異なるエンコーディングを使用することの柔軟性は、現実的というよりもむしろ理論的であるかのように思われます。これらの仕組みは今後のPostgreSQLのバージョンで使用されるようになるでしょう。
PostgreSQLで使用できる文字セットを表22-1に示します。
表 22-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_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-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 | |
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は、指定もしくはデフォルトのロケールに基づいて適当な符号化方式を決定しようとします。
もしCまたはPOSIXロケールを選択した場合は、異なる文字セットのデータベースを作成することができます。
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)
重要項目: On most modern operating systems, PostgreSQL can determine which character set is implied by an LC_CTYPE setting, and it will enforce that only the correct database encoding is used. On older systems it is your responsibility to ensure that you use the encoding expected by the locale you have selected. A mistake in this area is likely to lead to strange misbehavior of locale-dependent operations such as sorting.
最近のオペレーティングシステムでは、PostgreSQLは、LC_CTYPEの設定によりどの文字セットが指定されているか決定できます。また、ただ1つの正しいデータベースエンコーディングが使用されるようにできます。古いオペレーティングシステムでは、自分で選択したロケールによって期待されているエンコーディングを使用しているかを確認するのは各自の責任になります。ここでの間違いは、ソートといったようなロケールに依存する操作が、奇妙でおかしな動作するといったことにつながります。
PostgreSQL will allow superusers to create databases with SQL_ASCII encoding even when LC_CTYPE is not C or POSIX. As noted above, SQL_ASCII does not enforce that the data stored in the database has any particular encoding, and so this choice poses risks of locale-dependent misbehavior. Using this combination of settings is deprecated and may someday be forbidden altogether.
PostgreSQLは、LC_CTYPEがCもしくはPOSIXでもない場合にも、スーパユーザがSQL_ASCIIエンコーディングでデータベースを作成することを許可します。上記のように、SQL_ASCIIは、データベースに保存されているデータが特定のエンコーディングを持つことを強制しません。さらに、この選択はロケールに依存したおかしな動作を引き起こすリスクを高めます。この設定の組み合わせを使用することは、お勧めできませんし、いつの日か完全に禁止されるかもしれません。
PostgreSQLは、ある文字セットの組み合わせに対してサーバとクライアントの間で自動的に文字セットを変換する機能を提供しています。 変換情報はpg_conversionシステムカタログに格納されています。PostgreSQLには、表22-2で示されているように、事前に定義された変換が付属します。 新しい変換を作成するにはSQLコマンドのCREATE CONVERSIONを使用します。
表 22-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 (項30.9)はクライアントの符号化方式を制御する関数を保持しています。
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が定義されています。