Поддержка кодировок#

Примечание

Эта страница переведена при помощи нейросети GigaChat.

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

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

Поддерживаемые наборы символов#

В таблице ниже показаны наборы символов, доступные для использования в PostgreSQL.

Наборы символов PostgreSQL:

Имя

Описание

Язык

Сервер?

ICU?

Байт / Символ

Псевдонимы

BIG5

Большая пятерка

Традиционный китайский

Нет

Нет

1-2

WIN950, Windows950

EUC_CN

Расширенный код Юникода-CN

Упростите китайский

Да

Да

1-3

EUC_JP

Расширенный код Юникода для японского языка

Японский

Да

Да

1-3

EUC_JIS_2004

Расширенный код Юникода для Японии, JIS X 0213

Японский

Да

Нет

1–3

EUC_KR

Расширенный код Юникода-KR

Корейский

Да

Да

1-3

EUC_TW

Расширенный код Юникода-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, ЭМА 114

Латиница/Арабский

Да

Да

1

ISO_8859_7

ISO 8859-7, ЭМА 118

Латинский/греческий

Да

Да

1

ISO_8859_8

ISO 8859-8, ECMA 121

Латиница / Иврит

Да

Да

1

JOHAB

JOHAB

Корейский (Хангыль)

Нет

Нет

1-3

KOI8R

КОИ8-Р

Кириллица (русский)

Да

Да

1

KOI8

KOI8U

КОИ8-У

Не люблю менять тему разговора, но вот сейчас тот самый случай.

Да

Да

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

ЛАТИНСКИЙ1 с Евро и акцентами

Да

Да

1

ISO885915

LATIN10

ISO 8859-16, ASRO SR 14111

Румынский

Да

Нет

1

ISO885916

MULE_INTERNAL

Внутренний код мула

Многоязычный Эмакс

Да

Нет

1-4

SJIS

Shift JIS

Японский

Нет

Нет

1-2

Mskanji, ShiftJIS, WIN932, Windows932

SHIFT_JIS_2004

Shift JIS, JIS X 0213

Японский

Нет

Нет

1-2

SQL_ASCII

не указано (см. текст)

любое

Да

Нет

1

UHC

Унифицированный код хангыля

Корейский

Нет

Нет

1-2

WIN949, Windows949

UTF8

Юникод, 8 бит

все

Да

Да

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 поддерживают полный перечень заявленных кодировок. Например, драйвер PostgreSQL JDBC не поддерживает кодировки MULE_INTERNAL, LATIN6, LATIN8 и LATIN10.

Особенностью кодировки SQL_ASCII является ее особое поведение. При выборе серверной кодировки SQL_ASCII сервер интерпретирует байты от 0 до 127 как символы ASCII, а байты от 128 до 255 не интерпретирует вовсе. При использовании SQL_ASCII преобразование кодировок не выполняется. Фактически, эта настройка означает, что реальная кодировка неизвестна, а не задает конкретную кодировку. Чаще всего, если в данных содержатся символы, отличные от ASCII, использовать SQL_ASCII неэффективно, так как PostgreSQL не сможет оказывать помощь в преобразовании или проверке не-ASCII-символов.

Установка набора символов#

Инструмент initdb устанавливает набор символов (кодировку) по умолчанию для кластера PostgreSQL. Например:

initdb -E EUC_JP

определяет набор символов по умолчанию как EUC_JP (расширенный юникод-код для японского языка). Альтернативно можно использовать длинную форму параметра --encoding.

Если не указаны параметры -E или --encoding, initdb автоматически выберет подходящую кодировку на основе текущей локали.

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

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

Или эквивалентная команда SQL:

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

Эти команды создают базу данных с именем korean, использующую кодировку EUC_KR и локаль ko_KR. Обратите внимание, что здесь указано копирование из базы данных template0. При копировании любой другой базы данных параметры кодировки и локали должны совпадать с оригиналом, иначе это приведет к повреждению данных.

Кодировка базы данных хранится в системном каталоге 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 не гарантирует соблюдение конкретной кодировки хранимых данных, что увеличивает вероятность возникновения проблем, связанных с локализацией. Использование такого сочетания считается устаревшим и в будущем может быть запрещено.

Автоматическое преобразование набора символов между сервером и клиентом#

PostgreSQL поддерживает автоматическое преобразование наборов символов между сервером и клиентом для многих комбинаций кодировок (см. раздел Доступные преобразования набора символов для списка поддерживаемых преобразований).

Чтобы активировать автоматическое преобразование кодировок, необходимо указать PostgreSQL желаемую кодировку клиентского приложения. Это можно сделать несколькими способами:

  • Через команду \encoding в интерактивной оболочке psql. Например, для изменения кодировки на SJIS выполните:

    \encoding SJIS
    
  • С помощью функций библиотеки libpq (см. раздел Функции управления) для управления кодировкой клиента.

  • Путем использования команды SQL SET client_encoding TO. Например, для установки кодировки клиента на UTF8 выполните:

    SET client_encoding TO 'UTF8';
    
    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, сервер все равно проверяет, корректны ли поступающие данные для данной кодировки, поэтому общий эффект аналогичен случаю, когда клиентская и серверная кодировки совпадают.) Использование SQL_ASCII не оправдано, если работа ведется исключительно с данными в формате ASCII.

Доступные преобразования набора символов#

PostgreSQL позволяет выполнять преобразование между любыми двумя наборами символов, для которых существует соответствующая функция в системном каталоге pg_conversion. Postgres поставляется с некоторым количеством предопределенных преобразований, кратко описанных в таблице «Встроенные преобразования набора символов клиент/сервер» и подробно представленных в таблице «Все встроенные преобразования наборов символов». Добавить новое преобразование можно с помощью команды SQL CREATE CONVERSION. (Чтобы использовать преобразование автоматически при обмене данными между клиентом и сервером, оно должно быть отмечено как «по умолчанию» для данной пары наборов символов.)

Встроенные преобразования набора символов клиент/сервер:

Серверный набор символов

Доступные наборы символов клиента

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 до 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

Все встроенные преобразования наборов символов:

Имя преобразования

Исходная кодировка

Конечная кодировка

big5_to_euc_tw

BIG5

EUC_TW

big5_to_mic

BIG5

MULE_INTERNAL

big5_to_utf8

BIG5

UTF8

euc_cn_to_mic

EUC_CN

MULE_INTERNAL

euc_cn_to_utf8

EUC_CN

UTF8

euc_jp_to_mic

EUC_JP

MULE_INTERNAL

euc_jp_to_sjis

EUC_JP

SJIS

euc_jp_to_utf8

EUC_JP

UTF8

euc_kr_to_mic

EUC_KR

MULE_INTERNAL

euc_kr_to_utf8

EUC_KR

UTF8

euc_tw_to_big5

EUC_TW

BIG5

euc_tw_to_mic

EUC_TW

MULE_INTERNAL

euc_tw_to_utf8

EUC_TW

UTF8

gb18030_to_utf8

GB18030

UTF8

gbk_to_utf8

GBK

UTF8

iso_8859_10_to_utf8

LATIN6

UTF8

iso_8859_13_to_utf8

LATIN7

UTF8

iso_8859_14_to_utf8

LATIN8

UTF8

iso_8859_15_to_utf8

LATIN9

UTF8

iso_8859_16_to_utf8

LATIN10

UTF8

iso_8859_1_to_mic

LATIN1

MULE_INTERNAL

iso_8859_1_to_utf8

LATIN1

UTF8

iso_8859_2_to_mic

LATIN2

MULE_INTERNAL

iso_8859_2_to_utf8

LATIN2

UTF8

iso_8859_2_to_windows_1250

LATIN2

WIN1250

iso_8859_3_to_mic

LATIN3

MULE_INTERNAL

iso_8859_3_to_utf8

LATIN3

UTF8

iso_8859_4_to_mic

LATIN4

MULE_INTERNAL

iso_8859_4_to_utf8

LATIN4

UTF8

iso_8859_5_to_koi8_r

ISO_8859_5

KOI8R

iso_8859_5_to_mic

ISO_8859_5

MULE_INTERNAL

iso_8859_5_to_utf8

ISO_8859_5

UTF8

iso_8859_5_to_windows_1251

ISO_8859_5

WIN1251

iso_8859_5_to_windows_866

ISO_8859_5

WIN866

iso_8859_6_to_utf8

ISO_8859_6

UTF8

iso_8859_7_to_utf8

ISO_8859_7

UTF8

iso_8859_8_to_utf8

ISO_8859_8

UTF8

iso_8859_9_to_utf8

LATIN5

UTF8

johab_to_utf8

JOHAB

UTF8

koi8_r_to_iso_8859_5

KOI8R

ISO_8859_5

koi8_r_to_mic

KOI8R

MULE_INTERNAL

koi8_r_to_utf8

KOI8R

UTF8

koi8_r_to_windows_1251

KOI8R

WIN1251

koi8_r_to_windows_866

KOI8R

WIN866

koi8_u_to_utf8

KOI8U

UTF8

mic_to_big5

MULE_INTERNAL

BIG5

mic_to_euc_cn

MULE_INTERNAL

EUC_CN

mic_to_euc_jp

MULE_INTERNAL

EUC_JP

mic_to_euc_kr

MULE_INTERNAL

EUC_KR

mic_to_euc_tw

MULE_INTERNAL

EUC_TW

mic_to_iso_8859_1

MULE_INTERNAL

LATIN1

mic_to_iso_8859_2

MULE_INTERNAL

LATIN2

mic_to_iso_8859_3

MULE_INTERNAL

LATIN3

mic_to_iso_8859_4

MULE_INTERNAL

LATIN4

mic_to_iso_8859_5

MULE_INTERNAL

ISO_8859_5

mic_to_koi8_r

MULE_INTERNAL

KOI8R

mic_to_sjis

MULE_INTERNAL

SJIS

mic_to_windows_1250

MULE_INTERNAL

WIN1250

mic_to_windows_1251

MULE_INTERNAL

WIN1251

mic_to_windows_866

MULE_INTERNAL

WIN866

sjis_to_euc_jp

SJIS

EUC_JP

sjis_to_mic

SJIS

MULE_INTERNAL

sjis_to_utf8

SJIS

UTF8

windows_1258_to_utf8

WIN1258

UTF8

uhc_to_utf8

UHC

UTF8

utf8_to_big5

UTF8

BIG5

utf8_to_euc_cn

UTF8

EUC_CN

utf8_to_euc_jp

UTF8

EUC_JP

utf8_to_euc_kr

UTF8

EUC_KR

utf8_to_euc_tw

UTF8

EUC_TW

utf8_to_gb18030

UTF8

GB18030

utf8_to_gbk

UTF8

GBK

utf8_to_iso_8859_1

UTF8

LATIN1

utf8_to_iso_8859_10

UTF8

LATIN6

utf8_to_iso_8859_13

UTF8

LATIN7

utf8_to_iso_8859_14

UTF8

LATIN8

utf8_to_iso_8859_15

UTF8

LATIN9

utf8_to_iso_8859_16

UTF8

LATIN10

utf8_to_iso_8859_2

UTF8

LATIN2

utf8_to_iso_8859_3

UTF8

LATIN3

utf8_to_iso_8859_4

UTF8

LATIN4

utf8_to_iso_8859_5

UTF8

ISO_8859_5

utf8_to_iso_8859_6

UTF8

ISO_8859_6

utf8_to_iso_8859_7

UTF8

ISO_8859_7

utf8_to_iso_8859_8

UTF8

ISO_8859_8

utf8_to_iso_8859_9

UTF8

LATIN5

utf8_to_johab

UTF8

JOHAB

utf8_to_koi8_r

UTF8

KOI8R

utf8_to_koi8_u

UTF8

KOI8U

utf8_to_sjis

UTF8

SJIS

utf8_to_windows_1258

UTF8

WIN1258

utf8_to_uhc

UTF8

UHC

utf8_to_windows_1250

UTF8

WIN1250

utf8_to_windows_1251

UTF8

WIN1251

utf8_to_windows_1252

UTF8

WIN1252

utf8_to_windows_1253

UTF8

WIN1253

utf8_to_windows_1254

UTF8

WIN1254

utf8_to_windows_1255

UTF8

WIN1255

utf8_to_windows_1256

UTF8

WIN1256

utf8_to_windows_1257

UTF8

WIN1257

utf8_to_windows_866

UTF8

WIN866

utf8_to_windows_874

UTF8

WIN874

windows_1250_to_iso_8859_2

WIN1250

LATIN2

windows_1250_to_mic

WIN1250

MULE_INTERNAL

windows_1250_to_utf8

WIN1250

UTF8

windows_1251_to_iso_8859_5

WIN1251

ISO_8859_5

windows_1251_to_koi8_r

WIN1251

KOI8R

windows_1251_to_mic

WIN1251

MULE_INTERNAL

windows_1251_to_utf8

WIN1251

UTF8

windows_1251_to_windows_866

WIN1251

WIN866

windows_1252_to_utf8

WIN1252

UTF8

windows_1256_to_utf8

WIN1256

UTF8

windows_866_to_iso_8859_5

WIN866

ISO_8859_5

windows_866_to_koi8_r

WIN866

KOI8R

windows_866_to_mic

WIN866

MULE_INTERNAL

windows_866_to_utf8

WIN866

UTF8

windows_866_to_windows_1251

WIN866

WIN

windows_874_to_utf8

WIN874

UTF8

euc_jis_2004_to_utf8

EUC_JIS_2004

UTF8

utf8_to_euc_jis_2004

UTF8

EUC_JIS_2004

shift_jis_2004_to_utf8

SHIFT_JIS_2004

UTF8

utf8_to_shift_jis_2004

UTF8

SHIFT_JIS_2004

euc_jis_2004_to_shift_jis_2004

EUC_JIS_2004

SHIFT_JIS_2004

shift_jis_2004_to_euc_jis_2004

SHIFT_JIS_2004

EUC_JIS_2004

Имена преобразования следуют стандартной схеме именования: официальное название исходной кодировки со всеми неалфавитно-цифровыми символами, замененными подчеркиваниями, за которыми следует _to_, а затем аналогично обработанное имя целевой кодировки. Поэтому эти имена иногда отклоняются от обычных имен кодировок, показанных в таблице «Наборы символов PostgreSQL».

Дополнительная литература#

Эти материалы помогут разобраться в различных системах кодирования:

  • Обработка информации CJKV: вычисления на китайском, японском, корейском и вьетнамском языках

    Книга подробно объясняет стандарты кодирования EUC_JP, EUC_CN, EUC_KR, EUC_TW.

  • Веб-сайт консорциума Юникод

    Официальный ресурс, посвященный вопросам интернационализации и поддержке множества письменностей и языков.

  • RFC 3629

    Документ, определяющий формат UTF-8 (8-битное представление Юникода).