23.3. Поддержка кодировок
Поддержка кодировок в PostgreSQL позволяет хранить текст в различных кодировках, включая однобайтовые кодировки, такие как входящие в семейство ISO 8859 и многобайтовые кодировки, такие как EUC (Extended Unix Code), UTF-8 и внутренний код Mule. Все поддерживаемые кодировки могут прозрачно использоваться клиентами, но некоторые не поддерживаются сервером (в качестве серверной кодировки). Кодировка по умолчанию выбирается при инициализации кластера базы данных PostgreSQL при помощи initdb
. Она может быть переопределена при создании базы данных, что позволяет иметь несколько баз данных с разными кодировками.
Важным ограничением, однако, является то, что кодировка каждой базы данных должна быть совместима с параметрами локали базы данных LC_CTYPE
(классификация символов) и LC_COLLATE
(порядок сортировки строк). Для локали C
или POSIX
подойдёт любой набор символов, но для других локалей, предоставляемых библиотекой libc, есть только один набор символов, который будет работать правильно. (Однако в среде Windows кодировка UTF-8 может использоваться с любой локалью.) Если у вас включена поддержка ICU, локали, предоставляемые библиотекой ICU, можно использовать с большинством (но не всеми) кодировками на стороне сервера.
23.3.1. Поддерживаемые кодировки
Таблица 23.1 показывает кодировки, доступные для использования в PostgreSQL.
Таблица 23.1. Кодировки PostgreSQL
Имя | Описание | Язык | Поддержка на сервере | ICU? | Байтов на символ | Псевдонимы |
---|---|---|---|---|---|---|
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 | Национальный стандарт | Китайский | Нет | Нет | 1-4 | |
GBK | Расширенный национальный стандарт | Упрощённые китайские иероглифы | Нет | Нет | 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 | |
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-15 | LATIN1 c европейскими языками и диалектами | Да | Да | 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 |
SHIFT_JIS_2004 | Shift JIS, JIS X 0213 | Японский | Нет | Нет | 1-2 | |
SQL_ASCII | не указан (см. текст) | any | Да | Нет | 1 | |
UHC | Унифицированный код Хангыль | Корейский | Нет | Нет | 1-2 | WIN949 , 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 | Вьетнамский | Да | Да | 1 | ABC , 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.
23.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
. При копировании любой другой базы данных, параметры локали и кодировку исходной базы изменить нельзя, так как это может привести к искажению данных. Более подробное описание приведено в Разделе 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)
Важно
На большинстве современных операционных систем PostgreSQL может определить, какая кодировка подразумевается параметром LC_CTYPE
, что обеспечит использование только соответствующей кодировки базы данных. На более старых системах необходимо самостоятельно следить за тем, чтобы использовалась кодировка, соответствующая выбранной языковой среде. Ошибка в этой области, скорее всего, приведёт к странному поведению зависимых от локали операций, таких как сортировка.
PostgreSQL позволит суперпользователям создавать базы данных с кодировкой SQL_ASCII
, даже когда значение LC_CTYPE
не установлено в C
или POSIX
. Как было сказано выше, SQL_ASCII
не гарантирует, что данные, хранящиеся в базе, имеют определённую кодировку, и таким образом, этот выбор чреват сбоями, связанными с локалью. Использование данной комбинации устарело и, возможно, будет полностью запрещено.
23.3.3. Автоматическая перекодировка между сервером и клиентом
PostgreSQL поддерживает автоматическую перекодировку между сервером и клиентом для определённых комбинаций кодировок. Информация, касающаяся перекодировки, хранится в системном каталоге pg_conversion
. PostgreSQL включает в себя некоторые предопределённые кодировки, как показано в Таблице 23.2. Есть возможность создать новую перекодировку при помощи SQL-команды CREATE CONVERSION
.
Таблица 23.2. Клиент-серверные перекодировки наборов символов
Серверная кодировка | Доступные клиентские кодировки |
---|---|
BIG5 | не поддерживается как серверная кодировка |
EUC_CN | EUC_CN, MULE_INTERNAL , UTF8 |
EUC_JP | EUC_JP, MULE_INTERNAL , SJIS , UTF8 |
EUC_JIS_2004 | EUC_JIS_2004, SHIFT_JIS_2004 , 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 | не поддерживается как серверная кодировка |
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 | не поддерживается как серверная кодировка |
SHIFT_JIS_2004 | не поддерживается как серверная кодировка |
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 кодировку, которую вы хотели бы использовать на стороне клиента. Это можно выполнить несколькими способами:
Использование команды
\encoding
в psql.\encoding
позволяет оперативно изменять клиентскую кодировку. Например, чтобы изменить кодировку наSJIS
, введите:\encoding SJIS
libpq (Раздел 33.10) имеет функции, для управления клиентской кодировкой.
Использование
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.
23.3.4. Дополнительные источники информации
Рекомендуемые источники для начала изучения различных видов систем кодирования.
- Обработка информации на китайском, японском, корейском & вьетнамском языках.
Содержит подробные объяснения по
EUC_JP
,EUC_CN
,EUC_KR
,EUC_TW
.- http://www.unicode.org/
Сайт Unicode Consortium.
- RFC 3629
UTF-8 (формат преобразования 8-битного UCS/Unicode) определён здесь.