Локализация

В этой главе описываются доступные функции локализации с точки зрения администратора. QHB поддерживает два средства локализации:

  • Использование средств локализации операционной системы для обеспечения определяемых локалью порядка сортировки, форматирования чисел, перевода сообщений и других аспектов. Это описывается в разделах Поддержка языковых стандартов и Поддержка правил сортировки.

  • Предоставление ряда различных кодировок для поддержки хранения текста на разных языках и обеспечения перевода кодировок между клиентом и сервером. Это описывается в разделе Поддержка кодировок.



Поддержка языковых стандартов

В привязке к приложениям поддержка языковых стандартов позволяет учитывать культурные предпочтения в отношении алфавитов, сортировки, форматирования чисел и т. д. QHB использует стандартные средства локализации ISO C/RUST и POSIX, предоставляемые операционной системой сервера. Для получения дополнительной информации обратитесь к документации вашей системы.


Обзор

Поддержка языковых стандартов автоматически инициализируется при создании кластера баз данных с использованием qhb_bootstrap (или initdb). По умолчанию qhb_bootstrap инициализирует кластер баз данных с настройкой локали из среды выполнения, поэтому если ваша система уже настроена на использование локали, которую вы хотели бы видеть в своем кластере баз данных, то больше ничего не нужно делать. Если же вы хотите использовать другую локаль (или не уверены, для какой локали настроена ваша система), можно указать qhb_bootstrap, какую именно локаль использовать, установив параметр --locale. Например:

qhb_bootstrap --locale=ru_RU

Этот пример для систем Unix устанавливает локаль русского языка (ru), на котором говорят в России (RU). Другие возможности могут включать en_US (американский английский) и fr_CA (французский канадский). Если для локализации можно использовать более одного набора символов, тогда спецификации могут принимать форму язык_страна.кодировка. Например, ru_RU.utf8 представляет русский язык (ru), на котором говорят в России (RU), с кодировкой набора символов UTF-8.

То, какие локали доступны в вашей системе и под какими именами, зависит от того, что было предоставлено поставщиком операционной системы и что было установлено. В большинстве систем Unix команда locale -a выведет список доступных локалей.

Иногда бывает полезно смешать правила из нескольких локалей, например, использовать английские правила сортировки и сообщения на русском. Для поддержки этой возможности существует набор подкатегорий локалей, которые контролируют только определенные аспекты правил локализации:

КатегорияКонтролируемая область
LC_COLLATEПорядок сортировки строк
LC_CTYPEКлассификация символов (Что это за буква? Каков ее эквивалент в верхнем регистре?)
LC_MESSAGESЯзык сообщений
LC_MONETARYФорматирование денежных сумм
LC_NUMERICФорматирование чисел
LC_TIMEФорматирование даты и времени

Имена категорий переводятся в имена параметров qhb_bootstrap, чтобы переопределить выбор локали для конкретной категории. Например, чтобы установить локаль на канадский французский, но использовать правила США для форматирования валюты, используйте qhb_bootstrap --locale=fr_CA --lc-monetary=en_US.

Если вы хотите, чтобы система работала без поддержки локализаций, используйте специальное имя локали C или его эквивалент POSIX.

Значения некоторых категорий локалей должны быть заданы при создании базы данных. Для разных баз данных можно использовать разные значения, но как только база данных будет создана, вы больше не сможете их изменить. К этим категориям относятся LC_COLLATE и LC_CTYPE. Они влияют на порядок сортировки индексов, поэтому должны оставаться фиксированными, иначе могут повредиться индексы в текстовых столбцах. (Но это ограничение можно ослабить, используя параметры сортировки, как описано в разделе Поддержка правил сортировки). Значения по умолчанию для этих категорий определяются при запуске qhb_bootstrap, и эти значения используются при создании новых баз данных, если в команде CREATE DATABASE не указано иное.

Другие категории локалей можно изменить в любое время путем установки параметров конфигурации сервера с тем же именем, что и категории локализаций (подробности см. в подразделе Языковые стандарты и форматирование). Значения, выбранные qhb_bootstrap, на самом деле записываются только в файл конфигурации qhb.conf, чтобы служить значениями по умолчанию при запуске сервера. Если удалить эти назначения из qhb.conf, то сервер унаследует настройки из своей среды выполнения.

Обратите внимание, что поведение локали сервера определяется переменными среды, видимыми сервером, а не средой какого-либо клиента. Поэтому не забудьте сконфигурировать правильные параметры локали перед запуском сервера. Если клиент и сервер настроены с разными локалями, сообщения могут показываться на разных языках в зависимости от того, где они возникли.

Примечание
Наследование локали от среды выполнения в большинстве операционных систем означает следующее: для данной локали, скажем, сортировки, следующие переменные среды анализируются в приведенном ниже порядке, пока одна из них не окажется заданной: LC_ALL, LC_COLLATE (или переменная, относящаяся к соответствующей категории), LANG. Если ни одна из этих переменных среды не установлена, то по умолчанию в локали устанавливается значение C.

Некоторые библиотеки локализации сообщений при установке их языка также проверяют переменную среды LANGUAGE, переопределяющую все остальные параметры локали. В случае возникновения затруднений, пожалуйста, обратитесь к документации вашей операционной системы, в частности, к документации по gettext.

Чтобы разрешить перевод сообщений на предпочитаемый пользователем язык, во время сборки следует выбрать NLS (configure --enable-nls). В остальном поддержка языковых стандартов встроена автоматически.


Поведение

Настройки локали влияют на следующие возможности SQL:

  • Порядок сортировки в запросах с использованием ORDER BY или стандартных операторов сравнения текстовых данных

  • Функции upper, lower и initcap

  • Операторы сопоставления с шаблоном (LIKE, SIMILAR TO и регулярные выражения в стиле POSIX); локали влияют как на сопоставление без учета регистра, так и на классификацию символов по регулярным выражениям с классами символов

  • Семейство функций to_char

  • Возможность использовать индексы с предложениями LIKE.

Недостатком использования в QHB локалей, отличных от C или POSIX, является их влияние на производительность. Это замедляет обработку символов и не дает LIKE использовать обычные индексы. По этой причине используйте локали, только если они вам действительно нужны.

В качестве обходного пути, позволяющего QHB использовать индексы с предложениями LIKE в локали, отличной от C, существует несколько пользовательских классов операторов. Они позволяют создать индекс, который выполняет строгое посимвольное сравнение, игнорируя правила сравнения локали. Дополнительную информацию см. в разделе Классы операторов и семейства операторов. Другой подход заключается в создании индексов с использованием сортировки C, как описано в разделе Поддержка правил сортировки.


Проблемы

Если поддержка языковых стандартов не работает в соответствии с приведенным выше объяснением, проверьте, правильно ли настроена поддержка языковых стандартов в вашей операционной системе. Для проверки того, какие локали установлены в вашей системе, можно воспользоваться командой locale -a, если ваша операционная система ее предоставляет.

Убедитесь, что QHB действительно использует локаль, которая вам нужна. Параметры LC_COLLATE и LC_CTYPE определяются при создании базы данных и могут быть изменены только путем создания новой базы данных. Другие параметры локали, включая LC_MESSAGES и LC_MONETARY, первоначально определяются средой, в которой запущен сервер, но могут быть изменены на ходу. Параметры активной локали можно проверить, выполнив команду SHOW.

Клиентские приложения, обрабатывающие ошибки на стороне сервера путем синтаксического анализа текста сообщения об ошибке, определенно столкнутся с трудностями, когда сообщения сервера будут на другом языке. Авторам подобных приложений рекомендуется использовать вместо этого схему кодов ошибок.



Поддержка правил сортировки

Функция правил сортировки позволяет указать порядок сортировки и поведение классификации символов для каждого столбца или даже для каждой операции. Это смягчает имеющееся ограничение, что параметры базы данных LC_COLLATE и LC_CTYPE нельзя изменить после ее создания.


Концепции

Концептуально каждое выражение сортируемых данных имеет правило сортировки. (Встроенные типы данных — text, varchar и char. Пользовательские базовые типы тоже можно пометить как сортируемые, и, разумеется, домен на основе сортируемого типа данных тоже является сортируемым.) Если выражение является ссылкой на столбец, правило сортировки выражения определяется правилом сортировки столбца. Если выражение является константой, правилом сортировки является правило сортировки по умолчанию для типа данных константы. Правило сортировки более сложного выражения выводится из правил сортировки его входных данных, как описано ниже.

Правило сортировки выражения может быть правилом сортировки «по умолчанию», что означает применение параметров локали, определенных для базы данных. Кроме того, правило сортировки выражения может быть неопределимым. В таких случаях операции упорядочивания и другие операции, которые должны знать правило сортировки, завершатся ошибкой.

Когда СУБД должна выполнить упорядочивание или классификацию символов, она использует правило сортировки входного выражения. Это происходит, например, с предложениями ORDER BY и вызовами функций или операторов вроде <. Правило сортировки, применяемое для предложения ORDER BY, — это просто правило сортировочного ключа. Правило сортировки, применяемое для вызова функции или оператора, выводится из аргументов, как описано ниже. Помимо операторов сравнения правила сортировки учитываются функциями, преобразующими регистр букв из нижнего в верхний и наоборот, например lower, upper и initcap; операторами сопоставления с шаблоном; и функцией to_char и связанными с ней функциями.

При вызове функции или оператора правило сортировки, выводимое путем проверки правил сортировки аргументов, будет использовано во время выполнения указанной операции. Если результат вызова функции или оператора относится к сортируемому типу данных, то правило сортировки также используется во время синтаксического анализа в качестве определенного правила сортировки выражения функции или оператора, если существует окружающее выражение, требующее знания его правила сортировки.

Выведение правила сортировки выражения может быть явным или неявным. Это различие влияет на то, как комбинируются правила сортировки, когда в выражении появляются несколько различных правил сортировки. Явное выведение правил сортировки происходит, когда используется предложение COLLATE; все остальные выведения являются неявными. Когда необходимо скомбинировать несколько правил сортировки, например при вызове функции, используются следующие правила:

  1. Если какое-либо входное выражение имеет явно выведенное правило сортировки, то все явно выведенные правила сортировки среди входных выражений должны быть одинаковыми, иначе возникает ошибка. Если присутствует какое-либо явно выведенное правило сортировки, оно является результатом комбинирования правил сортировки.

  2. В противном случае все входные выражения должны иметь одинаковое неявно выведенное правило сортировки или правило сортировки по умолчанию. Если присутствует какое-либо правило сортировки, отличное от правила по умолчанию, оно является результатом комбинирования правил сортировки. В противном случае результатом является правило сортировки по умолчанию.

  3. Если среди входных выражений имеются конфликтующие неявные правила сортировки, отличные от правила по умолчанию, то считается, что комбинация имеет неопределяемое правило сортировки. Это не является условием возникновения ошибки, если конкретной вызываемой функции не требуется знание правила сортировки, которое она должна применять. Если же требуется, ошибка возникнет во время выполнения.

Например, рассмотрим это определение таблицы:

CREATE TABLE test1 (
a text COLLATE "de_DE",
b text COLLATE "es_ES",
...
);

Затем в запросе

SELECT a < 'foo' FROM test1;

сравнение < выполняется в соответствии с правилами de_DE, потому что выражение комбинирует неявно выведенное правило сортировки с правилом по умолчанию. Но в запросе

SELECT a < ('foo' COLLATE "fr_FR") FROM test1;

сравнение выполняется с использованием правил fr_FR, потому что явно выведенное правило сортировки переопределяет выведенное неявно. Более того, в запросе

SELECT a < b FROM test1;

синтаксический анализатор не может определить, какое правило сортировки применить, поскольку столбцы a и b имеют конфликтующие неявные правила сортировки. Поскольку оператору < необходимо знать, какое правило сортировки использовать, это приведет к ошибке. Ошибку можно устранить путем добавления явного спецификатора правила сортировки к любому входному выражению, например:

SELECT a < b COLLATE "de_DE" FROM test1;

или равнозначное ему

SELECT a COLLATE "de_DE" < b FROM test1;

С другой стороны, структурно похожий случай

SELECT a || b FROM test1;

не приводит к ошибке, потому что для оператора || правила сортировки не важны: его результат одинаков независимо от правила сортировки.

Правило сортировки, назначенное объединенным входным выражениям функции или оператора, также считается применимым к результату этой функции или оператора, если эта функция или оператор выдает в результате сортируемый тип данных. Поэтому запрос

SELECT * FROM test1 ORDER BY a || 'foo';

будет выполнен в соответствии с правилами de_DE . Но этот запрос:

SELECT * FROM test1 ORDER BY a || b;

приводит к ошибке, потому что даже если оператору || не нужно знать правило сортировки, предложению ORDER BY оно требуется. Как и выше, конфликт можно разрешить с помощью явного спецификатора правила сортировки:

SELECT * FROM test1 ORDER BY a || b COLLATE "fr_FR";

Управление правилами сортировки

Правила сортировки — это объект схемы SQL, который соотносит SQL-имя с локалями, предоставляемыми библиотеками, установленными в операционной системе. У определения правила сортировки есть провайдер, который указывает, какая библиотека предоставляет данные локали. Один стандартный провайдер с именем libc использует локали, предоставляемые библиотекой C операционной системы. Эти локали используются большинством инструментов, предоставляемых операционной системой. Другой провайдер, icu, использует внешнюю библиотеку ICU. Локали ICU можно использовать только в том случае, если при сборке QHB была настроена поддержка ICU.

Правило сортировки, предоставляемое libc, сопоставляется с комбинацией параметров LC_COLLATE и LC_CTYPE, принимаемой системным вызовом setlocale(). (Как следует из названия, основная цель правила сортировки состоит в том, чтобы установить LC_COLLATE, который управляет порядком сортировки. Но на практике редко требуется устанавливать в LC_CTYPE значение, отличное от LC_COLLATE, поэтому удобнее собирать их согласно одной концепции, чем создавать еще одну инфраструктуру, чтобы устанавливать LC_CTYPE для каждого выражения.) Кроме того, правило сортировки libc связано с кодировкой набора символов (см. раздел Поддержка кодировок). Одно и то же имя правила сортировки может существовать для разных кодировок.

Объект правила сортировки, предоставляемый icu, сопоставляется с именованным сортировщиком, предоставляемым библиотекой ICU. ICU не поддерживает отдельные настройки «collate» и «ctype», поэтому они всегда одинаковы. Кроме того, правила сортировки ICU не зависят от кодировки, поэтому в базе данных всегда есть только одно правило сортировки ICU с конкретным именем.


Стандартные правила сортировки

На всех платформах доступны правила сортировки с именами default, C и POSIX. В зависимости от поддержки операционной системы могут быть доступны дополнительные правила сортировки. Правила сортировки default выбирают значения LC_COLLATE и LC_CTYPE, указанные во время создания базы данных. Правила сортировки C и POSIX задают «традиционное поведение C», при котором только буквы ASCII от «A» до «Z» обрабатываются как буквы, а сортировка выполняется строго по значениям байтов кода символа.

Кроме того, для кодировки UTF8 доступно имя стандартного правила сортировки SQL ucs_basic. Оно равнозначно C и сортирует по кодовой точке Unicode.


Предопределенные правила сортировки

Если операционная система обеспечивает поддержку использования нескольких локалей в рамках одной программы (функция newlocale и связанные с ней) или если настроена поддержка ICU, то при инициализации кластера баз данных qhb_bootstrap заполняет системный каталог pg_collation правилами сортировки на основе всех локалей, которые она находит в операционной системе во время инициализации.

Чтобы проверить доступные в настоящее время локали, выполните запрос SELECT * FROM pg_collation или команду \dOS+ в psql.

Правила сортировки libc

Допустим, операционная система может предоставить локаль с именем de_DE.utf8. Тогда qhb_bootstrap создаст правило сортировки с именем de_DE.utf8 для кодировки UTF8, для которого в LC_COLLATE и LC_CTYPE установлено значение de_DE.utf8. Также она создаст правило сортировки с убранным из имени тегом .utf8. Таким образом, вы сможете использовать правило сортировки с менее громоздким и менее зависимым от кодировки именем de_DE. Обратите внимание, что начальный набор имен правил сортировки все равно зависит от платформы.

Набор правил сортировки по умолчанию, предоставляемый libc, сопоставляется непосредственно с локалями, установленными в операционной системе, список которых можно вывести с помощью команды locale -a. В случае, если требуется правило сортировки libc с разными значениями LC_COLLATE и LC_CTYPE или если в операционной системе после инициализации СУБД были установлены новые локали, то с помощью команды CREATE COLLATION можно создать новое правило сортировки. Кроме того, новые локали операционной системы можно массово импортировать с помощью функции pg_import_system_collations().

В любой конкретной базе данных представляют интерес только правила сортировки, использующие кодировку этой базы данных. Другие записи в pg_collation игнорируются. Таким образом, сокращенное имя правила сортировки, например de_DE, может считаться уникальным в отдельной базе данных, даже если оно не будет уникальным в глобальном масштабе. Рекомендуется использовать сокращенные имена правил сортировки, так как если вы решите перейти на другую кодировку базы данных, вам понадобится совершить на одно изменение меньше. Однако учтите, что правила сортировки default, C и POSIX можно использовать независимо от кодировки базы данных.

QHB считает, что отдельные объекты правил сортировки несовместимы, даже если они имеют идентичные свойства. Так, например,

SELECT a COLLATE "C" < b COLLATE "POSIX" FROM test1;

выдаст ошибку, даже если правила сортировки C и POSIX ведут себя одинаково. Поэтому не рекомендуется смешивать сокращенные и полные имена правил сортировки.

Правила сортировки ICU

С ICU не имеет смысла перечислять все возможные имена локалей. ICU использует для локалей определенную систему именования, но вариантов именования локали может быть гораздо больше, чем собственно различных локалей. qhb_bootstrap использует API ICU, чтобы извлечь набор различных локалей и заполнить начальный набор правил сортировки. Правила сортировки, предоставляемые ICU, создаются в среде SQL с именами в формате языкового тега BCP 47 с добавлением расширения «для частного использования», -x-icu, чтобы отличать их от локалей libc.

Вот несколько примеров правил сортировки, которые могут быть созданы:

de-x-icu

Немецкое правило сортировки, вариант по умолчанию

de-AT-x-icu

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

(Есть также, de-DE-x-icu или de-CH-x-icu, но на момент написания статьи они равнозначны de-x-icu).

und-x-icu («undefined», неопределенная)

«Корневое» правило сортировки ICU. Используйте его, чтобы получить разумный порядок сортировки, не зависящий от языка.

ICU не поддерживает некоторые (реже используемые) кодировки. Когда баз данных имеет одну из таких кодировок, записи правила сортировки ICU в pg_collation игнорируются. Попытка его использовать приведет к появлению ошибки и строки вида «правило сортировки «de-x-icu» для кодировки «WIN874» не существует».


Создание новых правил сортировки

Если стандартных и предопределенных правил сортировки недостаточно, пользователи могут создавать собственные правила сортировки с помощью команды SQL CREATE COLLATION.

Стандартные и предопределенные параметры сортировки находятся в схеме pg_catalog, как и все предопределенные объекты. Пользовательские правила сортировки должны создаваться в пользовательских схемах. Это также гарантирует, что они сохраняются qhb_dump.

Правила сортировки libc

Новые правила сортировки libc можно создать следующим образом:

CREATE COLLATION german (provider = libc, locale = 'de_DE');

Точные значения, принимаемые предложением locale в этой команде, зависят от операционной системы. В Unix-подобных системах их список покажет команда locale -a.

Поскольку предопределенные правила сортировки libc уже включают в себя все правила, определенные в операционной системе при инициализации кластера баз данных, нет необходимости создавать новые вручную. Такая необходимость может возникнуть в том случае, если желательна другая система именования (в этом случае см. подраздел Копирование правил сортировки ) или если операционная система была обновлена, и в ней появились новые определения локалей (в этом случае см. также pg_import_system_collations()).

Правила сортировки ICU

ICU позволяет настраивать правила сортировки вне базового набора язык+страна, который предварительно загружается qhb_bootstrap. Пользователям рекомендуется определять собственные правила сортировки, использующие базовые средства для получения сортировки, соответствующей их требованиями. Информация о именовании локалей ICU доступна на страницах http://userguide.icu-project.org/locale и http://userguide.icu-project.org/collation/api. Набор допустимых имен и атрибутов зависит от конкретной версии ICU.

Вот некоторые примеры:

CREATE COLLATION "de-u-co-phonebk-x-icu" (provider = icu, locale = 'de-u-co-phonebk');
CREATE COLLATION "de-u-co-phonebk-x-icu" (provider = icu, locale = 'de@collation=phonebook');

Немецкая сортировка с типом сортировки, как в телефонной книге.

В первом примере выбирается локаль ICU с использованием «языкового тега» формата BCP 47. Во втором примере используется традиционный синтаксис локали, специфичный для ICU. Первый стиль предпочтительнее в дальнейшем, но он не поддерживается старыми версиями ICU.

Обратите внимание, что в среде SQL вы можете называть правила сортировки как угодно. В этом примере мы следуем стилю именования, используемым предопределенными правилами сортировки, которые, в свою очередь, также следуют BCP 47, но для пользовательских правил сортировки это не требуется.

CREATE COLLATION "und-u-co-emoji-x-icu" (provider = icu, locale = 'und-u-co-emoji');
CREATE COLLATION "und-u-co-emoji-x-icu" (provider = icu, locale = '@collation=emoji');

Корневое правило сортировки типа эмодзи, соответствующее техническому стандарту Unicode #51.

В традиционной системе именования локалей ICU корневая локаль выбирается пустой строкой.

CREATE COLLATION digitslast (provider = icu, locale = 'en-u-kr-latn-digit');
CREATE COLLATION digitslast (provider = icu, locale = 'en@colReorder=latn-digit');

Сортировка, в которой цифры идут после латинских букв. (По умолчанию сначала идут цифры.)

CREATE COLLATION upperfirst (provider = icu, locale = 'en-u-kf-upper');
CREATE COLLATION upperfirst (provider = icu, locale = 'en@colCaseFirst=upper');

Сортировка в которой заглавные буквы идут перед строчными. (По умолчанию сначала идут строчные буквы.)

CREATE COLLATION special (provider = icu, locale = 'en-u-kf-upper-kr-latn-digit');
CREATE COLLATION special (provider = icu, locale = 'en@colCaseFirst=upper;colReorder=latn-digit');

Комбинация двух вышеуказанных вариантов.

CREATE COLLATION numeric (provider = icu, locale = 'en-u-kn-true');
CREATE COLLATION numeric (provider = icu, locale = 'en@colNumeric=yes');

Числовой порядок, сортирующий последовательности цифр по их числовому значению, например: A-21 < A-123 (также известный как естественная сортировка).

Подробности см. в описании технического стандарта Unicode #35 и BCP 47. Список возможных типов сортировки (субтег co) можно найти в репозитории CLDR. Для просмотра деталей конкретного определения локали можно использовать ICU Locale Explorer. Для примеров, использующих субтеги k* требуется ICU как минимум версии 54.

Обратите внимание, что хотя эта система позволяет создавать правила сортировки, которые «игнорируют регистр» или «игнорируют ударения» или аналогичные (с помощью ключа ks), для того, чтобы такие правила сортировки действительно работали без учета регистра или ударения, они также должны быть объявлены в CREATE COLLATION как недетерминированные ; см. подраздел Недетерминированные правила сортировки. В противном случае любые строки, которые считаются равными согласно правилу сортировки, но не являются равными побайтово, будут отсортированы в соответствии со своими байтовыми значениями.

Примечание
По своей конструкции ICU будет принимать в качестве имени локали практически любую строку и сопоставлять ее с наиболее подходящей из предоставляемых им локалей, используя процедуру нейтрализации неисправности, описанную в его документации. Таким образом, если спецификация правила сортировки составлена с использованием функций, которые данная установка ICU фактически не поддерживает, прямого сообщения об этом не будет. Поэтому для проверки того, что определения правил сортировки удовлетворяют требованиям, рекомендуется создавать контрольные примеры на уровне приложения.

Копирование правил сортировки

Команду CREATE COLLATION также можно использовать для создания нового правила сортировки из уже существующего правила, благодаря чему появляется возможность использовать независимые от операционной системы имена правил в приложениях, создавать совместимые имена или использовать правила, предоставляемые ICU, в более читаемом формате. Например:

CREATE COLLATION german FROM "de_DE";

CREATE COLLATION french FROM "fr-x-icu";

Недетерминированные правила сортировки

Правило сортировки является либо детерминированным, либо недетерминированным. Детерминированное правило использует детерминированные сравнения, то есть оно считает строки равными, только если они состоят из одинаковой последовательности байтов. Недетерминированное сравнение может определить строки как равные, даже если они состоят из разных байтов. Типичные ситуации включают сравнение без учета регистра или ударения, а также сравнение строк в различных нормальных формах Unicode. Фактическая реализация таких сравнений определяется провайдером правил сортировки; флаг детерминированности определяет только то, должно ли равенство решаться побайтовым сравнением. Дополнительную информацию по терминологии см. в описании технического стандарта Unicode 10.

Чтобы создать недетерминированное правило сортировки, укажите в команде CREATE COLLATION свойство deterministic = false, например:

CREATE COLLATION ndcoll (provider = icu, locale = 'und', deterministic = false);

В этом примере стандартное правило сортировки Unicode будет работать недетерминированным образом. В частности, это позволит правильно сравнивать строки в разных нормальных формах. В более интересных случаях используются описанные выше средства настройки ICU. Например:

CREATE COLLATION case_insensitive (provider = icu, locale = 'und-u-ks-level2', deterministic = false);
CREATE COLLATION ignore_accents (provider = icu, locale = 'und-u-ks-level1-kc-true', deterministic = false);

Все стандартные и предопределенные правила сортировки являются детерминированными, все определяемые пользователем параметры сортировки также по умолчанию являются детерминированными. Хотя недетерминированные правила сортировки ведут себя более «правильно», особенно если учитывать все возможности Unicode и его множество особых случаев, у них имеются и некоторые недостатки. Прежде всего, их применение приводит к снижению производительности. Кроме того, с недетерминированными правилами невозможно проводить некоторые операции, например операции сопоставления с шаблоном. Поэтому их следует использовать только в тех случаях, когда они явно необходимы.

Совет
Для эффективной обработки текста в различных формах нормализации Unicode также можно использовать функции/выражения normalize и is normalized, позволяющие предварительно обработать или проверить строки, не прибегая к использованию недетерминированных правил сортировки. Однако каждый подход имеет свои минусы.

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

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

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

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

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

Таблица 1. Кодировки QHB

ИмяОписаниеЯзыкПоддержка на сервереICU?Байт на символПсевдонимы
BIG5Big FiveТрадиционный китайскийНетНет1-2WIN950, Windows950
EUC_CNРасширенный код UNIX-CNУпрощенный китайскийДаДа1-3
EUC_JPРасширенный код UNIX-JPЯпонскийДаДа1-3
EUC_JIS_2004Расширенный код UNIX-JP, JIS X 0213ЯпонскийДаНет1-3
EUC_KRРасширенный код UNIX-KRКорейскийДаДа1-3
EUC_TWРасширенный код UNIX-TWТрадиционный китайский, тайваньскийДаДа1-3
GB18030Национальный стандартКитайский языкНетНет1-4
GBKРасширенный национальный стандартУпрощенный китайскийНетНет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
KOI8RKOI 8-RКириллица (Русский)ДаДа1KOI8
KOI8UKOI 8-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-15LATIN1 с европейскими языками и диакритикойДаДа1ISO885915
LATIN10ISO 8859-16, ASRO SR 14111РумынскийДаНет1ISO885916
MULE_INTERNALВнутренний код MuleМногоязычный редактор EmacsДаНет1-4
SJISShift JISЯпонскийНетНет1-2Mskanji, ShiftJIS, WIN932, Windows932
SHIFT_JIS_2004Shift JIS, JIS X 0213ЯпонскийНетНет1-2
SQL_ASCIIне указано (см. текст)любыеДаНет1
UHCУнифицированный код ХангыльКорейскийНетНет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 поддерживают все перечисленные кодировки. Например, драйвер QHB JDBC не поддерживает MULE_INTERNAL, LATIN6, LATIN8 и LATIN10.

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

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

qhb_bootstrap определяет набор символов (кодировку) по умолчанию для кластера QHB. Например,

qhb_bootstrap -E EUC_JP

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

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

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. При копировании любой другой базы данных параметры кодировки и локали исходной базы изменить нельзя, поскольку это может привести к повреждению данных. Дополнительную информацию см. в разделе Шаблоны баз данных.

Кодировка базы данных хранится в системном каталоге qhb_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)

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

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

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

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

Чтобы включить автоматическую перекодировку, нужно сообщить QHB набор символов (кодировку), который вы бы хотели использовать на стороне клиента. Это можно сделать несколькими способами:

  • Использование команды \encoding в psql. \encoding позволяет менять клиентскую кодировку на ходу. Например, для изменения кодировки на SJIS введите:

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

  • Использование SET client_encoding TO. Установить клиентскую кодировку можно этой командой SQL:

    SET CLIENT_ENCODING TO 'значение';
    

    Также для этой цели можно использовать стандартные синтаксис SQL SET NAMES:

    SET NAMES 'значение';
    

    Запросить текущую клиентскую кодировку:

    SHOW client_encoding;
    

    Вернуть кодировку по умолчанию:

    RESET client_encoding;
    
  • Использование PGCLIENTENCODING. Если в клиентской среде определена переменная среды PGCLIENTENCODING, заданная клиентская кодировка выбирается автоматически при подключении к серверу. (В последующем это можно переопределить с помощью любого из описанных выше методов.)

  • Использование переменной конфигурации client_encoding. Если установлена переменная client_encoding, заданная клиентская кодировка выбирается автоматически при подключении к серверу. (В последующем это можно переопределить с помощью любого из описанных выше методов.)

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

Если кодировка клиента определена как SQL_ASCII, перекодировка отключается вне зависимости от кодировки сервера. (Однако если кодировка сервера отличается от SQL_ASCII, сервер все равно будет проверять входные данные на допустимость для его кодировки, поэтому конечный результат будет таким же, как если бы кодировка клиента совпадала с кодировкой сервера.) Так же, как и для сервера, использование SQL_ASCII неразумно, кроме случаев, когда данные, с которыми вы работаете, полностью соответствуют ASCII.

Доступные перекодировки

QHB допускает преобразования между любыми двумя кодировками, для которых в системном каталоге pg_conversion имеется функция перекодирования. QHB поставляется с несколькими предопределенными перекодировками, перечисленными в Таблице 2 и подробнее описанными в Таблице 3. Можно создать и новую перекодировку, воспользовавшись командой SQL CREATE CONVERSION. (Чтобы применяться для автоматических клиент-серверных перекодировок, она должна быть помечена как перекодировка «по умолчанию» для своей пары кодировок.)

Таблица 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
JOHABне поддерживается в качестве серверной кодировки
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 - 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

Таблица 3. Все встроенные перекодировки

Имя преобразования 1Исходная кодировкаЦелевая кодировка
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
1

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

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

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

CJKV Information Processing: Chinese, Japanese, Korean & Vietnamese Computing
Содержит подробные объяснения по EUC_JP, EUC_CN, EUC_KR, EUC_TW.

http://www.unicode.org/
Сайт Консорциума Unicode.

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