Локализация

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

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

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

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

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

Обзор

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

initdb --locale=ru_RU

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

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

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

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

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

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

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

Другие категории языковых стандартов могут быть изменены в любое время путем установки параметров конфигурации сервера, которые имеют то же имя, что и категории локализаций (подробности см. в разделе Языковые стандарты и форматирование). Значения, выбранные initdb, на самом деле записываются только в файл конфигурации 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_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» обрабатываются как буквы, а сортировка выполняется строго по значениям байтов кода символа.

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

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

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

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

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

Например, операционная система может предоставить локализацию с именем de_DE.utf8. Тогда initdb создаст сопоставление с именем 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 имя правила, такое как de_DE может считаться уникальным в данной базе данных, даже если оно не будет уникальным в глобальном масштабе. Рекомендуется использовать сокращенные имена параметров сортировки, так как вам придётся делать на одну вещь меньше, если вы решите перейти на другую кодировку базы данных. Однако обратите внимание, что правила default, C и POSIX могут использоваться независимо от кодировки базы данных.

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

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

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

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

С ICU не имеет смысла перечислять все возможные названия локализаций. ICU использует определённую систему именования для локализаций, но существует гораздо больше названий локализаций, чем на самом деле разных локализаций. initdb использует 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 (for “undefined”)

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

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

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

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

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

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

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

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

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

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

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

ICU позволяет настраивать параметры сортировки вне базового набора языка+страны, который предварительно загружен initdb. Пользователям рекомендуется определять свои собственные правила сортировки, которые используют базовые средства для соответствия поведению сортировки их требованиям. См. http://userguide.icu-project.org/locale и http://userguide.icu-project.org/collation/api для получения информации о наименовании локализации ICU. Набор допустимых имён и атрибутов зависит от конкретной версии 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');
  • Корневое правило сортировки с типом сортировки 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 (расширенный код Unix), UTF-8 и внутренний код Mule. Все поддерживаемые кодировки могут прозрачно использоваться клиентами, но некоторые из них не поддерживаются для использования на сервере (то есть в качестве кодировки на стороне сервера). Кодировка по умолчанию выбирается при инициализации кластера баз данных QHB с помощью initdb. Ее можно переопределить при создании базы данных, что позволяет иметь несколько баз данных с разными кодировками.

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

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

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

initdb -E EUC_JP

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

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