Локализация

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

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

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

Внимание!!!
Текущая версия QHB поддерживает наборы символов, перечисленные в разделе Поддержка набора символов. Однако предпочтительной кодировкой базы данных является UTF-8, и в следующих релизах 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.

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

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

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

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

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

имяОписаниеязыкПоддержка на сервереICU?Байтов на символПсевдонимы
BIG5Большая ПятеркаТрадиционный китайскийнетнет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 121Latin / Hebrewдада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 поддерживают все перечисленные наборы символов. Например, драйвер 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. При копировании любой другой базы данных параметры кодировки и локализации нельзя изменить по сравнению с исходной базой данных, поскольку это может привести к повреждению данных. Для получения дополнительной информации см. раздел Базы данных шаблонов.

Кодировка для базы данных хранится в системном каталоге pg_database. Вы можете увидеть это, используя команду psql \l.

$ psql -l

List of databases

Name        | Owner | Encoding | Collate     | Ctype       | Access privileges
------------+-------+----------+-------------+-------------+------------------------------------
mydb        | qhb   | UTF8     | en_US.UTF-8 | en_US.UTF-8 |
qhb         | qhb   | UTF8     | en_US.UTF-8 | en_US.UTF-8 |
template0   | qhb   | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/qhb + qhb=CTc/qhb
template1   | qhb   | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/qhb + qhb=CTc/qhb
tpc         | qhb   | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =Tc/qhb + qhb=CTc/qhb + tpc=CTc/qhb
(5 rows)

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

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

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

QHB поддерживает автоматическое преобразование набора символов между сервером и клиентом для определенных комбинаций набора символов. Информация о преобразовании хранится в системном каталоге pg_conversion. QHB поставляется с некоторыми предопределенными преобразованиями, как показано в таблице 2. Вы можете создать новое преобразование с помощью 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
LATIN5ЛАТИН5, 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

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

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

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

SET CLIENT_ENCODING TO 'value';
  • Также вы можете использовать стандартный синтаксис SET NAMES для этой цели:
SET NAMES 'value';
  • Чтобы запросить текущую кодировку клиента:
SHOW client_encoding;
  • Чтобы вернуться к кодировке по умолчанию:
RESET client_encoding;
  • Использование PGCLIENTENCODING. Если переменная среды PGCLIENTENCODING определена в среде клиента, эта кодировка клиента выбирается автоматически при установлении соединения с сервером. (Это может впоследствии быть переопределено, используя любой из других методов, упомянутых выше).

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

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

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

Дальнейшее чтение

Следующие источники можно использовать для начала изучения различных видов систем кодирования.

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) определяется здесь.

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

Функция сортировки позволяет указать порядок сортировки и классификацию символов для каждого столбца или даже для каждой операции. Это 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+ в qsql.

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

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