22.2. 文字セットサポート

PostgreSQLの文字セット(エンコーディングとも呼ばれます)サポートにより、ISO 8859シリーズなどのシングルバイト文字やEUC(拡張Unixコード)、UTF-8、Mule内部コードなどのマルチバイト文字を含む、各種文字セットでテキストを保存することができます。 全ての文字セットはクライアントにより透過的に使用することができますが、いくつかは、サーバ内での(つまりサーバサイドエンコーディングとして)使用はサポートされていません。デフォルトの文字セットは、initdbを使用したPostgreSQLデータベースクラスタの初期化時に決定されます。 これは、データベースを作成する時に上書きすることができるので、異なる文字セットを使用した複数のデータベースを持つことができます。

しかし重要な制限は、それぞれのデータベースの文字セットがサーバのLC_CTYPE設定と互換性が無くてはいけません。 LC_CTYPECもしくはPOSIXのときは、どのような文字セットも許可されています。 しかし、他のLC_CTYPEの設定のときは、正しく動作する文字セットはひとつだけとなります。 LC_CTYPE設定がinitdbにより凍結されているため、(実際のロケール認識を無効化させる)C or POSIXロケールを選択したときを除いては、クラスタの異なるデータベースで用いられる異なるエンコーディングを使用することの柔軟性は、現実的というよりもむしろ理論的であるかのように思われます。これらの仕組みは今後のPostgreSQLのバージョンで使用されるようになるでしょう。

22.2.1. サポートされる文字セット

PostgreSQLで使用できる文字セットを表22-1に示します。

表 22-1. PostgreSQL文字セット

名前説明言語サーバ?バイト数/文字別名
BIG5Big Five従来の中国語1-2いいえWIN950Windows950
EUC_CNExtended UNIX Code-CN簡易中国語はい1-3 
EUC_JPExtended UNIX Code-JP日本語はい1-3 
EUC_JIS_2004Extended UNIX Code-JP, JIS X 0213日本語はい1-3 
EUC_KRExtended UNIX Code-KR韓国語はい1-3 
EUC_TWExtended UNIX Code-TW従来の中国語、台湾語はい1-3 
GB18030National Standard中国語いいえ1-2 
GBKExtended National Standard簡易中国語いいえ1-2WIN936Windows936
ISO_8859_5ISO 8859-5、ECMA 113ラテン/キリルはい1 
ISO_8859_6ISO 8859-6、ECMA 114ラテン/アラビア語はい1 
ISO_8859_7ISO 8859-7、ECMA 118ラテン/ギリシャ語はい1 
ISO_8859_8ISO 8859-8、ECMA 121ラテン/ヘブライ語はい1 
JOHABJOHAB韓国語(ハングル語)いいえ1-3 
KOI8KOI8-R(U)キリル語はい1KOI8R
LATIN1ISO 8859-1、ECMA 94西ヨーロッパはい1ISO88591
LATIN2ISO 8859-2、ECMA 94中央ヨーロッパはい1ISO88592
LATIN3ISO 8859-3、ECMA 94南ヨーロッパはい1ISO88593
LATIN4ISO 8859-4、ECMA 94北ヨーロッパはい1ISO88594
LATIN5ISO 8859-9、ECMA 128トルコはい1ISO88599
LATIN6ISO 8859-10、ECMA 144北欧はい1ISO885910
LATIN7ISO 8859-13バルト諸国はい1ISO885913
LATIN8ISO 8859-14ケルトはい1ISO885914
LATIN9ISO 8859-15LATIN1でヨーロッパと訛りを含むはい1ISO885915
LATIN10ISO 8859-16、ASRO SR 14111ルーマニアはい1ISO885916
MULE_INTERNALMule内部コード多言語Emacsはい1-4 
SJISShift JIS日本語いいえ1-2MskanjiShiftJISWIN932Windows932
SQL_ASCII未指定(テキストを参照)何でもはい1 
SHIFT_JIS_2004Shift JIS, JIS X 0213日本語いいえ1-2 
SQL_ASCII未指定(テキストを参照)何でもはい1 
UHC統合ハングルコード韓国語いいえ1-2WIN949Windows949
UTF8Unicode、8ビットすべてはい1-4Unicode
WIN866Windows CP866キリル語はい1ALT
WIN874Windows CP874タイ語はい1 
WIN1250Windows CP1250中央ヨーロッパはい1 
WIN1251Windows CP1251キリル語はい1WIN
WIN1252Windows CP1252西ヨーロッパはい1 
WIN1253Windows CP1253ギリシャはい1 
WIN1254Windows CP1254トルコはい1 
WIN1255Windows CP1255ヘブライはい1 
WIN1256Windows CP1256アラビア語はい1 
WIN1257Windows CP1257バルティックはい1 
WIN1258Windows CP1258ベトナム語はい1ABCTCVNTCVN5712VSCII

全てのAPIが上の一覧表に示した文字セットをサポートしているわけではありません。 例えばPostgreSQL JDBCドライバはMULE_INTERNALLATIN6LATIN8、そしてLATIN10をサポートしません。

SQL_ASCIIの設定は、他の設定とかなり異なります。サーバのキャラクタセットがSQL_ASCIIのとき、サーバは0から127のバイト値をASCIIに変換します。一方、128から255までは変換されません。 設定がSQL_ASCIIの場合は、符号化は実行されません。よって、この設定は特定の符号化を使用している場合には、その符号化を無視するようになってしまいます。 多くの場合、ASCIIではない環境で作業する場合はSQL_ASCIIの設定を使用するのは、賢いことではありません。なぜならPostgreSQLはASCIIではない文字を変換したり検査したりすることは出来ないからです。

22.2.2. 文字セットの設定

initdbPostgreSQLクラスタのデフォルト文字セットを定義します。 以下に例を示します。

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_CTYPECもしくはPOSIXでもない場合にも、スーパユーザがSQL_ASCIIエンコーディングでデータベースを作成することを許可します。上記のように、SQL_ASCIIは、データベースに保存されているデータが特定のエンコーディングを持つことを強制しません。さらに、この選択はロケールに依存したおかしな動作を引き起こすリスクを高めます。この設定の組み合わせを使用することは、お勧めできませんし、いつの日か完全に禁止されるかもしれません。

22.2.3. サーバ・クライアント間の自動文字セット変換

PostgreSQLは、ある文字セットの組み合わせに対してサーバとクライアントの間で自動的に文字セットを変換する機能を提供しています。 変換情報はpg_conversionシステムカタログに格納されています。PostgreSQLには、表22-2で示されているように、事前に定義された変換が付属します。 新しい変換を作成するにはSQLコマンドのCREATE CONVERSIONを使用します。

表 22-2. クライアント・サーバ文字セット変換

サーバ文字セット利用可能なクライアント文字セット
BIG5サーバの符号化方式としてはサポートしていません。
EUC_CNEUC_CNMULE_INTERNALUTF8
EUC_JPEUC_JPMULE_INTERNALSJISUTF8
EUC_KREUC_KRMULE_INTERNALUTF8
EUC_TWEUC_TWBIG5MULE_INTERNALUTF8
GB18030サーバの符号化方式としてはサポートしていません。
GBKサーバの符号化方式としてはサポートしていません。
ISO_8859_5ISO_8859_5KOI8MULE_INTERNALUTF8WIN866WIN1251
ISO_8859_6ISO_8859_6UTF8
ISO_8859_7ISO_8859_7UTF8
ISO_8859_8ISO_8859_8UTF8
JOHABJOHABUTF8
KOI8KOI8ISO_8859_5MULE_INTERNALUTF8WIN866WIN1251
LATIN1LATIN1MULE_INTERNALUTF8
LATIN2LATIN2MULE_INTERNALUTF8WIN1250
LATIN3LATIN3MULE_INTERNALUTF8
LATIN4LATIN4MULE_INTERNALUTF8
LATIN5LATIN5UTF8
LATIN6LATIN6UTF8
LATIN7LATIN7UTF8
LATIN8LATIN8UTF8
LATIN9LATIN9UTF8
LATIN10LATIN10UTF8
MULE_INTERNALMULE_INTERNALBIG5EUC_CNEUC_JPEUC_KREUC_TWISO_8859_5KOI8LATIN1 to LATIN4SJISWIN866WIN1250WIN1251
SJISサーバの符号化方式としてはサポートしていません。
SQL_ASCIIどれでも (変換されません)
UHCサーバの符号化方式としてはサポートしていません。
UTF8すべてサポートされています。
WIN866WIN866ISO_8859_5KOI8MULE_INTERNALUTF8WIN1251
WIN874WIN874UTF8
WIN1250WIN1250LATIN2MULE_INTERNALUTF8
WIN1251WIN1251ISO_8859_5KOI8MULE_INTERNALUTF8WIN866
WIN1252WIN1252UTF8
WIN1253WIN1253, UTF8
WIN1254WIN1254, UTF8
WIN1255WIN1255, UTF8
WIN1256WIN1256UTF8
WIN1257WIN1257, UTF8
WIN1258WIN1258UTF8

自動文字セット変換を有効にするためには、クライアントでどのような文字セット(符号化方式)を使用させたいかをPostgreSQLに伝えなければなりません。 これを行うにはいくつかの方法があります。

EUC_JPをサーバに、そしてLATIN1をクライアントに選んだ場合のように、特定の文字の変換ができない時、日本語文字はLATIN1に入っていないのでエラーが報告されます。

クライアント側のキャラクタセットがSQL_ASCIIに定義されている場合は、符号化変換はサーバ側のキャラクタセットに関係無く無効化されます。 サーバ側と同じように、SQL_ASCIIを使用することは、すべてASCIIのデータを扱っている場合を除き、賢い方法ではありません。

22.2.4. 推奨文書

ここに記したものは様々な符号化方式システムを学習するのに良い資料です。

http://www.i18ngurus.com/docs/984813247.html

An extensive collection of documents about character sets, encodings, and code pages.

ftp://ftp.ora.com/pub/examples/nutshell/ujip/doc/cjk.inf

3.2節にEUC_JPEUC_CNEUC_KREUC_TWの詳しい説明があります。

http://www.unicode.org/

Unicode協会のWebサイトです。

RFC 3629

ここでUTF-8が定義されています。

アダルトレンタルサーバー