23.3. 문자 집합 지원

PostgreSQL에서 지원하는 문자 집합을 사용하면 ISO 8859 같은 싱글바이트 문자 집합 및 EUC(Extended Unix Code), UTF-8, 뮬 내부코드 같은 멀티바이트 문자 집합을 비롯한 다양한 문자 집합으로 텍스트를 저장할 수 있다. 지원되는 모든 문자 집합은 클라이언트에서 사용 가능한 것이 확실하지만, 몇 가지는 서버 내에서의 사용이 지원되지 않는다(즉, 서버 측 인코딩). 기본 문자 집합은 initdb를 사용하여 PostgreSQL 데이터베이스 클러스터를 초기화하면서 선택된다. 오버라이드는 데이터베이스를 생성할 때 가능하므로 복수의 데이터베이스 각각 문자 집합이 서로 다를 수 있다.

하지만, 각 데이터베이스 문자 집합은 데이터베이스의 LC_CTYPE(문자 분류) 및 LC_COLLATE(string 정렬 순서) 로케일(locale) 설정과 호환되어야 한다는 중요한 제약이 있다. C 또는 POSIX 로케일(locale)의 경우 임의의 문자 집합이 허용되지만, 다른 로케일(locale)의 경우 올바로 작동되는 문자 집합은 하나밖에 없다. (그러나 Windows의 경우 UTF-8 인코딩은 모든 로케일(locale)에서 사용할 수 있다.)

23.3.1. 지원되는 문자 집합

표 23-1PostgreSQL에서 사용할 수 있는 문자 집합을 보여준다.

표 23-1. PostgreSQL 문자 집합

이름설명언어서버?바이트/문자별칭
BIG5Big Five중국어 번체아니요1-2WIN950, Windows950
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-4 
GBKExtended National Standard중국어 간체아니요1-2WIN936, Windows936
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 
KOI8RKOI8-R키릴어 (러시아어)1KOI8
KOI8UKOI8-U키릴어 (우크라이나어)1 
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-15유로 및 액센트 사용 LATIN11ISO885915
LATIN10ISO 8859-16, ASRO SR 14111루마니아어1ISO885916
MULE_INTERNALMule 내부 코드Multilingual Emacs1-4 
SJISShift JIS일본어아니요1-2Mskanji, ShiftJIS, WIN932, Windows932
SHIFT_JIS_2004Shift JIS, JIS X 0213일본어아니요1-2 
SQL_ASCII미지정 (텍스트 참조)아무거나1 
UHCUnified Hangul Code한국어아니요1-2WIN949, Windows949
UTF8유니코드, 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베트남어1ABC, TCVN, TCVN5712, VSCII

모든 클라이언트 API가 나열된 모든 문자 집합을 지원하는 것은 아니다. 예를 들면, PostgreSQL JDBC 드라이버는 MULE_INTERNALLATIN6, LATIN8, LATIN10을 지원하지 않는다.

SQL_ASCII 설정은 다른 설정과 상당히 다르게 동작한다. 서버 문자 집합이 SQL_ASCII인 경우 서버는 ASCII 표준에 따라 바이트 값 0-127을 해석하고, 바이트 값 128-255은 해석 불가 문자로 처리한다. 설정이 SQL_ASCII인 경우 인코딩 변환이 완료되지 않는다. 따라서 이 설정은 사용 중인 특정 인코딩에 대한 선언이라기 보다는 인코딩에 대한 무시 선언이다. 대부분의 경우에, ASCII가 아닌 데이터를 사용하는 경우 PostgreSQL은 비 ASCII 문자를 변환하거나 검증할 수 없기 때문에 SQL_ASCII 설정을 사용하는 것은 현명하지 않다.

23.3.2. 문자 집합 설정

initdbPostgreSQL 클러스터에 대한 기본 문자 집합(인코딩)을 정의한다. 예를 들면,

initdb -E EUC_JP

이것은 기본 문자 집합을 EUC_JP (Extended Unix Code for Japanese)로 설정한다. 옵션 string이 긴 것을 선호하는 경우 --encoding-E 대신 사용할 수 있다. -E 또는 --encoding 옵션을 지정하지 않으면 initdb는 지정되었거나 기본 로케일(locale)을 기반으로 사용할 적정 인코딩을 결정하려고 한다.

인코딩이 선택한 로케일(locale)과 호환되는 경우 사용자는 기본값이 아닌 인코딩을 데이터베이스 생성 시에 지정할 수 있다.

createdb -E EUC_KR -T template0 --lc-collate=ko_KR.euckr --lc-ctype=ko_KR.euckr korean

이것은 문자 집합 EUC_KR 및 로케일(locale) ko_KR을 사용하는 korean이라는 데이터베이스를 생성한다. 다른 방법으로 아래와 같은 SQL 명령을 사용할 수 있다.

CREATE DATABASE korean WITH ENCODING 'EUC_KR' LC_COLLATE='ko_KR.euckr' LC_CTYPE='ko_KR.euckr' TEMPLATE=template0;

위의 명령은 template0 데이터베이스 복사를 지정한다는 점에 유의하라. 다른 데이터베이스를 복사할 때 데이터 손상의 우려 때문에 원본 데이터베이스로부터 인코딩과 로케일(locale) 설정은 변경할 수 없다. 자세한 내용은 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)

중요: 대부분의 최신 운영 체제에서 PostgreSQLLC_CTYPE 설정에 의해 어떤 문자 집합이 암시되는지를 판단하며, 강제로 일치되는 데이터베이스 인코딩만 사용되도록 한다. 예전 시스템에서는 선택한 로케일(locale)에서 예상되는 올바른 인코딩을 사용하는 것이 사용자의 책임이었다. 여기서 실수를 했을 경우 정렬 같이 로케일(locale)에 의존적인 작업은 이상하게 동작한다.

PostgreSQLLC_CTYPEC또는 POSIX가 아니더라도 수퍼유저가 SQL_ASCII 인코딩을 사용하여 데이터베이스를 생성하는 것을 가능하게 한다. 위에서 명시한 대로, SQL_ASCII는 데이터베이스에 저장된 데이터가 특정한 인코딩을 강제로 갖게 하지 않으므로 SQL_ASCII을 선택하면 로케일(locale)에 의존적인 동작은 잘못될 가능성이 있다. 이러한 설정 조합은 사용할 수 없으며 언젠가는 전면적으로 금지될 수 있다.

23.3.3. 서버와 클라이언트 간 자동 문자 집합 변환

PostgreSQL은 서버와 클라이언트 간 특정 문자 집합 조합에 대해 자동 문자 집합 변환을 지원한다. 변환 정보는 pg_conversion 시스템 카탈로그에 저장된다. PostgreSQL표 23-2에 나오는 사전 정의된 변환 몇 가지를 제공한다. SQL 명령 CREATE CONVERSION을 사용하면 새로운 변환을 생성할 수 있다.

표 23-2. 클라이언트/서버 문자 집합 변환

서버 문자 집합사용 가능한 클라이언트 문자 집합
BIG5서버 인코딩으로 지원되지 않음
EUC_CNEUC_CN, MULE_INTERNAL, UTF8
EUC_JPEUC_JP, MULE_INTERNAL, SJIS, UTF8
EUC_KREUC_KR, MULE_INTERNAL, UTF8
EUC_TWEUC_TW, BIG5, MULE_INTERNAL, UTF8
GB18030서버 인코딩으로 지원되지 않음
GBK서버 인코딩으로 지원되지 않음
ISO_8859_5ISO_8859_5, KOI8R, MULE_INTERNAL, UTF8, WIN866, WIN1251
ISO_8859_6ISO_8859_6, UTF8
ISO_8859_7ISO_8859_7, UTF8
ISO_8859_8ISO_8859_8, UTF8
JOHABJOHAB, UTF8
KOI8RKOI8R, ISO_8859_5, MULE_INTERNAL, UTF8, WIN866, WIN1251
KOI8UKOI8U, UTF8
LATIN1LATIN1, MULE_INTERNAL, UTF8
LATIN2LATIN2, MULE_INTERNAL, UTF8, WIN1250
LATIN3LATIN3, MULE_INTERNAL, UTF8
LATIN4LATIN4, MULE_INTERNAL, UTF8
LATIN5LATIN5, UTF8
LATIN6LATIN6, UTF8
LATIN7LATIN7, UTF8
LATIN8LATIN8, UTF8
LATIN9LATIN9, UTF8
LATIN10LATIN10, UTF8
MULE_INTERNALMULE_INTERNAL, BIG5, EUC_CN, EUC_JP, EUC_KR, EUC_TW, ISO_8859_5, KOI8R, LATIN1 to LATIN4, SJIS, WIN866, WIN1250, WIN1251
SJIS서버 인코딩으로 지원되지 않음
SQL_ASCII아무거나(변환이 수행되지 않음)
UHC서버 인코딩으로 지원되지 않음
UTF8인코딩 모두 지원
WIN866WIN866, ISO_8859_5, KOI8R, MULE_INTERNAL, UTF8, WIN1251
WIN874WIN874, UTF8
WIN1250WIN1250, LATIN2, MULE_INTERNAL, UTF8
WIN1251WIN1251, ISO_8859_5, KOI8R, MULE_INTERNAL, UTF8, WIN866
WIN1252WIN1252, UTF8
WIN1253WIN1253, UTF8
WIN1254WIN1254, UTF8
WIN1255WIN1255, UTF8
WIN1256WIN1256, UTF8
WIN1257WIN1257, UTF8
WIN1258WIN1258, UTF8

자동 문자 집합 변환을 활성화하려면 클라이언트에서 사용하려는 문자 집합(인코딩)을 PostgreSQL에 알려 주어야 한다. 이렇게 하는 방법에는 몇 가지가 있다.

특정한 문자 변환이 불가능한 경우 사용자가 서버에 대해서는 EUC_JP를 선택하고 클라이언트에 대해서는 LATIN1을 선택한 것으로 추정되며, LATIN1 표현이 없는 일본어 문자가 리턴된다. 에러가 리포트된다.

클라이언트 문자 집합이 SQL_ASCII로 설정된 경우 서버의 문자 집합과 무관하게 인코딩 변환이 비활성화된다. 서버의 경우처럼 모든 ASCII 데이터를 사용하지 않을 때는 SQL_ASCII는 바람직하지 않다.

23.3.4. 추가 자료

이 소스는 다양한 인코딩 시스템을 배우는 데 도움이 된다.

CJKV Information Processing: Chinese, Japanese, Korean & Vietnamese Computing

EUC_JP, EUC_CN, EUC_KR, EUC_TW에 대한 자세한 설명이 나와 있다.

http://www.unicode.org/

유니코드 컨소시엄 웹사이트.

RFC 3629

UTF-8 (8-bit UCS/Unicode Transformation Format)가 여기에 정의되어 있다.