22.3. Поддержка кодировок

Поддержка кодировок в PostgreSQL позволяет хранить текст в различных кодировках, включая однобайтовые кодировки, такие как входящие в семейство ISO 8859 и многобайтовые кодировки, такие как EUC (Extended Unix Code), UTF-8 и внутренний код Mule. Все поддерживаемые кодировки могут прозрачно использоваться клиентами, но некоторые не поддерживаются сервером (в качестве серверной кодировки). Кодировка по умолчанию выбирается при инициализации кластера базы данных PostgreSQL при помощи initdb. Она может быть переопределена при создании базы данных, что позволяет иметь несколько баз данных с разными кодировками.

Важным ограничением, однако, является то, что кодировка каждой базы данных должна быть совместима с параметрами локали базы данных LC_CTYPE (классификация символов) и LC_COLLATE (порядок сортировки строк). Для локали C или POSIX подойдёт любой набор символов, но для других локалей есть только одна кодировка, которая будет работать правильно. (Однако, в среде Windows кодировка UTF-8 может использоваться с любой локалью.)

22.3.1. Поддерживаемые кодировки

Таблица 22-1 показывает кодировки, доступные для использования в PostgreSQL.

Таблица 22-1. Кодировки PostgreSQL

ИмяОписаниеЯзыкПоддержка на сервереБайтов на символПсевдонимы
BIG5 Big FiveТрадиционные китайские иероглифыНет1-2WIN950, 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 Национальный стандартКитайскийНет1-4 
GBK Расширенный национальный стандартУпрощённые китайские иероглифыНет1-2WIN936, 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 
KOI8R KOI8-RКириллица (Русский)Да1 KOI8
KOI8U KOI8-UКириллица (Украинский)Да1 
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-15LATIN1 c европейскими языками и диалектамиДа1 ISO885915
LATIN10 ISO 8859-16, ASRO SR 14111РумынскийДа1 ISO885916
MULE_INTERNAL Внутренний код MuleМультиязычный редактор EmacsДа1-4 
SJIS Shift JISЯпонскийНет1-2Mskanji, ShiftJIS, WIN932, Windows932
SHIFT_JIS_2004 Shift JIS, JIS X 0213ЯпонскийНет1-2 
SQL_ASCII не указан (см. текст) any Да1 
UHC Унифицированный код ХангыльКорейскийНет1-2WIN949, Windows949
UTF8 Unicode, 8-bit все Да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ВьетнамскийДа1ABC, TCVN, TCVN5712, VSCII

Не все клиентские API поддерживают все перечисленные кодировки. Например, драйвер интерфейса JDBC PostgreSQL не поддерживает MULE_INTERNAL, LATIN6, LATIN8 и LATIN10.

Поведение кодировки SQL_ASCII существенно отличается от других. Когда набором символов сервера является SQL_ASCII, сервер интерпретирует значения от 0 до 127 байт согласно кодировке ASCII, тогда как значения от 128 до 255 воспринимаются как незначимые. Перекодировка не будет выполнена при выборе SQL_ASCII. Таким образом, этот вариант является не столько объявлением того, что используется определённая кодировка, сколько объявлением того, что кодировка игнорируется. В большинстве случаев, если вы работаете с любыми данными, отличными от ASCII, не стоит использовать SQL_ASCII, так как PostgreSQL не сможет преобразовать или проверить символы, отличные от ASCII.

22.3.2. Настройка кодировки

initdb определяет кодировку по умолчанию для кластера PostgreSQL. Например,

initdb -E EUC_JP

настраивает кодировку по умолчанию на EUC_JP (Расширенная система кодирования для японского языка). Можно использовать --encoding вместо -E в случае предпочтения более длинных имён параметров. Если параметр -E или --encoding не задан, initdb пытается определить подходящую кодировку в зависимости от указанной или заданной по умолчанию локали.

При создании базы данных можно указать кодировку, отличную от заданной по умолчанию, если эта кодировка совместима с выбранной локалью:

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

Это создаст базу данных с именем korean, которая использует кодировку EUC_KR и локаль ko_KR. Также, получить желаемый результат можно с помощью данной SQL-команды:

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

Заметьте, что приведённые выше команды задают копирование базы данных template0. При копировании любой другой базы данных, параметры локали и кодировку исходной базы изменить нельзя, так как это может привести к искажению данных. Более подробное описание приведено в Разделе 21.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)

Важно: На большинстве современных операционных систем PostgreSQL может определить, какая кодировка подразумевается параметром LC_CTYPE, что обеспечит использование только соответствующей кодировки базы данных. На более старых системах необходимо самостоятельно следить за тем, чтобы использовалась кодировка, соответствующая выбранной языковой среде. Ошибка в этой области, скорее всего, приведёт к странному поведению зависимых от локали операций, таких как сортировка.

PostgreSQL позволит суперпользователям создавать базы данных с кодировкой SQL_ASCII, даже когда значение LC_CTYPE не установлено в C или POSIX. Как было сказано выше, SQL_ASCII не гарантирует, что данные, хранящиеся в базе, имеют определённую кодировку, и таким образом, этот выбор чреват сбоями, связанными с локалью. Использование данной комбинации устарело и, возможно, будет полностью запрещено.

22.3.3. Автоматическая перекодировка между сервером и клиентом

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, KOI8R, 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
KOI8R KOI8R, ISO_8859_5, MULE_INTERNAL, UTF8, WIN866, WIN1251
KOI8U KOI8U, UTF8
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, KOI8R, LATIN1 to LATIN4, SJIS, WIN866, WIN1250, WIN1251
SJIS не поддерживается как серверная кодировка
SQL_ASCII любая (перекодировка не будет выполнена)
UHC не поддерживается как серверная кодировка
UTF8 все поддерживаемые кодировки
WIN866 WIN866, ISO_8859_5, KOI8R, MULE_INTERNAL, UTF8, WIN1251
WIN874 WIN874, UTF8
WIN1250 WIN1250, LATIN2, MULE_INTERNAL, UTF8
WIN1251 WIN1251, ISO_8859_5, KOI8R, 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 кодировку, которую вы хотели бы использовать на стороне клиента. Это можно выполнить несколькими способами:

Если перекодировка определённого символа невозможна (предположим, выбраны EUC_JP для сервера и LATIN1 для клиента, и передаются некоторые японские иероглифы, не представленные в LATIN1), возникает ошибка.

Если клиентская кодировка определена как SQL_ASCII, перекодировка отключается вне зависимости от кодировки сервера. Что же касается сервера, не стоит использовать SQL_ASCII, если только вы не работаете с данными, которые полностью соответствуют ASCII.

22.3.4. Дополнительные источники информации

Рекомендуемые источники для начала изучения различных видов систем кодирования.

Обработка информации на китайском, японском, корейском & вьетнамском языках.

Содержит подробные объяснения по EUC_JP, EUC_CN, EUC_KR, EUC_TW.

http://www.unicode.org/

Сайт Unicode Consortium.

RFC 3629

UTF-8 (формат преобразования 8-битного UCS/Unicode) определён здесь.