23.3. 문자 집합 지원

23.3.1. 지원되는 문자 집합
23.3.2. 문자 집합 설정
23.3.3. 서버와 클라이언트 간 자동 문자 집합 변환
23.3.4. 사용 가능한 문자 집합 변환
23.3.5. 추가 자료

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

하지만, 각 데이터베이스 문자 집합은 데이터베이스의 LC_CTYPE(문자 분류) 및 LC_COLLATE(string 정렬 순서) 로케일(locale) 설정과 호환되어야 한다는 중요한 제약이 있다. C 또는 POSIX 로케일(locale)의 경우 멀티바이트 문자 집합이 허용되지만, libc 라이브러리에 기반한 다른 로케일(locale)의 경우 싱글바이트 문자 집합에 대해서만 정상 작동한다. (그러나 Windows의 경우 UTF-8 인코딩은 모든 로케일(locale)에서 사용할 수 있다.) If you have ICU support configured, ICU-provided locales can be used with most but not all server-side encodings.

23.3.1. 지원되는 문자 집합

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

표 23.1. PostgreSQL 문자 집합

이름설명언어서버?ICU?바이트/​문자별칭
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 Emacs아니요1–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은 서버와 클라이언트 간 특정 문자 집합 조합에 대해 자동 문자 집합 변환을 지원한다. (23.3.4절 참조)

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

  • psql에서 \encoding 명령 사용. \encoding을 사용하면 클라이언트 인코딩을 그때그때 변경할 수 있다. 예를 들면, 인코딩을 SJIS로 변경하려면 다음을 입력한다.

    \encoding SJIS
    

  • libpq(33.10절)에는 클라이언트 인코딩을 제어하는 기능이 있다.

  • SET client_encoding TO 사용.

    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 데이터를 사용하지 않을 때는 SQL_ASCII는 바람직하지 않다.

23.3.4. 사용 가능한 문자 집합 변환

PostgreSQLpg_conversion 시스템 카탈로그 테이블 안에 정의된 변환 함수를 이용해서 두 문자 집합 간 변환을 할 수 있다. PostgreSQL표 23.2 표에서 처럼 미리 정의된 변환을 사용할 수 있으며, 보다 자세한 설명은 표 23.3 표에서 설명한다. 또한 사용자 정의 변환 규칙도 만들수 있는데, 이는 CREATE CONVERSION SQL 명령으로 할 수 있다. (클라이언트/서버간 자동 문자 집합 변환도 가능한데, 이 때는 그 변환에 default 옵션을 지정해야 한다.)

표 23.2. 내장 클라이언트/서버 문자 집합 변환

서버 문자 집합사용 가능한 클라이언트 문자 집합
BIG5서버 인코딩으로 지원하지 않음
EUC_CNEUC_CN, MULE_INTERNAL, UTF8
EUC_JPEUC_JP, MULE_INTERNAL, SJIS, UTF8
EUC_JIS_2004EUC_JIS_2004, SHIFT_JIS_2004, 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
JOHABnot supported as a server encoding
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서버 인코딩으로 지원하지 않음
SHIFT_JIS_2004서버 인코딩으로 지원하지 않음
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

표 23.3. 모든 내장 문자 집합 변환

변환 이름 [a] 입력 인코딩출력 인코딩
big5_to_euc_twBIG5EUC_TW
big5_to_micBIG5MULE_INTERNAL
big5_to_utf8BIG5UTF8
euc_cn_to_micEUC_CNMULE_INTERNAL
euc_cn_to_utf8EUC_CNUTF8
euc_jp_to_micEUC_JPMULE_INTERNAL
euc_jp_to_sjisEUC_JPSJIS
euc_jp_to_utf8EUC_JPUTF8
euc_kr_to_micEUC_KRMULE_INTERNAL
euc_kr_to_utf8EUC_KRUTF8
euc_tw_to_big5EUC_TWBIG5
euc_tw_to_micEUC_TWMULE_INTERNAL
euc_tw_to_utf8EUC_TWUTF8
gb18030_to_utf8GB18030UTF8
gbk_to_utf8GBKUTF8
iso_8859_10_to_utf8LATIN6UTF8
iso_8859_13_to_utf8LATIN7UTF8
iso_8859_14_to_utf8LATIN8UTF8
iso_8859_15_to_utf8LATIN9UTF8
iso_8859_16_to_utf8LATIN10UTF8
iso_8859_1_to_micLATIN1MULE_INTERNAL
iso_8859_1_to_utf8LATIN1UTF8
iso_8859_2_to_micLATIN2MULE_INTERNAL
iso_8859_2_to_utf8LATIN2UTF8
iso_8859_2_to_windows_1250LATIN2WIN1250
iso_8859_3_to_micLATIN3MULE_INTERNAL
iso_8859_3_to_utf8LATIN3UTF8
iso_8859_4_to_micLATIN4MULE_INTERNAL
iso_8859_4_to_utf8LATIN4UTF8
iso_8859_5_to_koi8_rISO_8859_5KOI8R
iso_8859_5_to_micISO_8859_5MULE_INTERNAL
iso_8859_5_to_utf8ISO_8859_5UTF8
iso_8859_5_to_windows_1251ISO_8859_5WIN1251
iso_8859_5_to_windows_866ISO_8859_5WIN866
iso_8859_6_to_utf8ISO_8859_6UTF8
iso_8859_7_to_utf8ISO_8859_7UTF8
iso_8859_8_to_utf8ISO_8859_8UTF8
iso_8859_9_to_utf8LATIN5UTF8
johab_to_utf8JOHABUTF8
koi8_r_to_iso_8859_5KOI8RISO_8859_5
koi8_r_to_micKOI8RMULE_INTERNAL
koi8_r_to_utf8KOI8RUTF8
koi8_r_to_windows_1251KOI8RWIN1251
koi8_r_to_windows_866KOI8RWIN866
koi8_u_to_utf8KOI8UUTF8
mic_to_big5MULE_INTERNALBIG5
mic_to_euc_cnMULE_INTERNALEUC_CN
mic_to_euc_jpMULE_INTERNALEUC_JP
mic_to_euc_krMULE_INTERNALEUC_KR
mic_to_euc_twMULE_INTERNALEUC_TW
mic_to_iso_8859_1MULE_INTERNALLATIN1
mic_to_iso_8859_2MULE_INTERNALLATIN2
mic_to_iso_8859_3MULE_INTERNALLATIN3
mic_to_iso_8859_4MULE_INTERNALLATIN4
mic_to_iso_8859_5MULE_INTERNALISO_8859_5
mic_to_koi8_rMULE_INTERNALKOI8R
mic_to_sjisMULE_INTERNALSJIS
mic_to_windows_1250MULE_INTERNALWIN1250
mic_to_windows_1251MULE_INTERNALWIN1251
mic_to_windows_866MULE_INTERNALWIN866
sjis_to_euc_jpSJISEUC_JP
sjis_to_micSJISMULE_INTERNAL
sjis_to_utf8SJISUTF8
windows_1258_to_utf8WIN1258UTF8
uhc_to_utf8UHCUTF8
utf8_to_big5UTF8BIG5
utf8_to_euc_cnUTF8EUC_CN
utf8_to_euc_jpUTF8EUC_JP
utf8_to_euc_krUTF8EUC_KR
utf8_to_euc_twUTF8EUC_TW
utf8_to_gb18030UTF8GB18030
utf8_to_gbkUTF8GBK
utf8_to_iso_8859_1UTF8LATIN1
utf8_to_iso_8859_10UTF8LATIN6
utf8_to_iso_8859_13UTF8LATIN7
utf8_to_iso_8859_14UTF8LATIN8
utf8_to_iso_8859_15UTF8LATIN9
utf8_to_iso_8859_16UTF8LATIN10
utf8_to_iso_8859_2UTF8LATIN2
utf8_to_iso_8859_3UTF8LATIN3
utf8_to_iso_8859_4UTF8LATIN4
utf8_to_iso_8859_5UTF8ISO_8859_5
utf8_to_iso_8859_6UTF8ISO_8859_6
utf8_to_iso_8859_7UTF8ISO_8859_7
utf8_to_iso_8859_8UTF8ISO_8859_8
utf8_to_iso_8859_9UTF8LATIN5
utf8_to_johabUTF8JOHAB
utf8_to_koi8_rUTF8KOI8R
utf8_to_koi8_uUTF8KOI8U
utf8_to_sjisUTF8SJIS
utf8_to_windows_1258UTF8WIN1258
utf8_to_uhcUTF8UHC
utf8_to_windows_1250UTF8WIN1250
utf8_to_windows_1251UTF8WIN1251
utf8_to_windows_1252UTF8WIN1252
utf8_to_windows_1253UTF8WIN1253
utf8_to_windows_1254UTF8WIN1254
utf8_to_windows_1255UTF8WIN1255
utf8_to_windows_1256UTF8WIN1256
utf8_to_windows_1257UTF8WIN1257
utf8_to_windows_866UTF8WIN866
utf8_to_windows_874UTF8WIN874
windows_1250_to_iso_8859_2WIN1250LATIN2
windows_1250_to_micWIN1250MULE_INTERNAL
windows_1250_to_utf8WIN1250UTF8
windows_1251_to_iso_8859_5WIN1251ISO_8859_5
windows_1251_to_koi8_rWIN1251KOI8R
windows_1251_to_micWIN1251MULE_INTERNAL
windows_1251_to_utf8WIN1251UTF8
windows_1251_to_windows_866WIN1251WIN866
windows_1252_to_utf8WIN1252UTF8
windows_1256_to_utf8WIN1256UTF8
windows_866_to_iso_8859_5WIN866ISO_8859_5
windows_866_to_koi8_rWIN866KOI8R
windows_866_to_micWIN866MULE_INTERNAL
windows_866_to_utf8WIN866UTF8
windows_866_to_windows_1251WIN866WIN
windows_874_to_utf8WIN874UTF8
euc_jis_2004_to_utf8EUC_JIS_2004UTF8
utf8_to_euc_jis_2004UTF8EUC_JIS_2004
shift_jis_2004_to_utf8SHIFT_JIS_2004UTF8
utf8_to_shift_jis_2004UTF8SHIFT_JIS_2004
euc_jis_2004_to_shift_jis_2004EUC_JIS_2004SHIFT_JIS_2004
shift_jis_2004_to_euc_jis_2004SHIFT_JIS_2004EUC_JIS_2004

[a] 변환 이름은 표준 이름 규칙을 따른다: 인코딩 이름은 알파벳과 숫자가 아닌 모든 문자는 밑줄(_)로 바꾸고, 입력 인코딩 이름 다음 _to_ 문자열이 오고, 다음 출력 인코딩 이름으로 구성된다. 그래서, 몇몇은 표 23.1 표에 있는 이름과 다르다.


23.3.5. 추가 자료

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

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

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

https://www.unicode.org/

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

RFC 3629

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