Перейти к основному содержимому

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

примечание

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

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

Обзор

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

initdb --locale=sv_SE

В данном примере для Unix-системы устанавливается шведская локаль (sv_SE). Возможны и другие комбинации, например, американский английский (en_US) или канадский французский (fr_CA). Если для региона предусмотрено несколько наборов символов, спецификацию можно записать в формате язык_страна.кодировка, например, fr_BE.UTF-8 означает французский язык (Франция), Бельгия, с использованием кодировки UTF-8.

Доступные локали и их наименования зависят от поставщика операционной системы и установленной конфигурации. В большинстве UNIX-систем список доступных локалей можно вывести командой locale -a. В Windows используются более детализированные названия, такие как 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 и заносятся в файл конфигурации postgresql.conf, где служат значениями по умолчанию при запуске сервера. Если удалить эти параметры из postgresql.conf, сервер будет использовать локаль, установленную в своей среде исполнения.

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

Примечание

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

  • LC_ALL
  • Переменная, соответствующая искомой категории (например, LC_COLLATE)
  • LANG

Если ни одна из этих переменных не определена, локаль устанавливается в значение по умолчанию — C.

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

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

Поведение

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

  • Результат сортировки в запросах с конструкцией ORDER BY и стандартных операторов сравнения для текстовых данных.
  • Функции upper, lower и initcap.
  • Регулярные выражения и операторы сопоставления (LIKE, SIMILAR TO, POSIX-style regexp), локали влияют как на чувствительность к регистру, так и на распознавание классов символов.
  • Семейство функций to_char.
  • Возможность эффективно использовать индексы с условиями LIKE.

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

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

Выбор локалей

Выбор локали может осуществляться на разных уровнях в зависимости от потребностей. Ранее обсудили, как локали назначаются через initdb для установки начальных значений на уровне всего кластера. Далее рассмотрим уровни, на которых можно задавать локали. Каждый пункт предоставляет значения по умолчанию для последующих уровней, которые можно переопределить:

  1. Окружение операционной системы задает значения по умолчанию для локалей при инициализации нового кластера баз данных. Зачастую этого достаточно: если операционная система настроена нужным языком и регионом, PostgreSQL автоматически будет использовать соответствующие настройки.
  2. Аргументы командной строки для initdb позволяют задать локали для всего кластера при его инициализации. Применяйте этот способ, если операционная система не удовлетворяет потребности в отношении локали.
  3. Локаль можно задать отдельно для каждой базы данных. Для этого предназначена команда SQL CREATE DATABASE и ее аналог в терминальной программе createdb. Используйте этот подход, если кластеру требуются базы данных с различными требованиями к локализации.
  4. Локальность можно задать и на уровне отдельных столбцов таблицы. Для этого используются объекты SQL, называемые сопоставлениями, подробнее об этом рассказано в разделе Поддержка сборки. Используйте этот метод, если необходимо сортировать данные на разных языках или задать уникальную схему сортировки для конкретной таблицы.
  5. Наконец, локаль можно выбрать для отдельного запроса, опять-таки используя объекты сопоставления SQL. Это пригодится для экспериментов или динамического изменения порядка сортировки во время выполнения.

Поставщики локалей

PostgreSQL поддерживает несколько источников локалей, определяющих, какую библиотеку использовать для обработки национальных стандартов. Стандартный поставщик называется libc, он применяет локали, предоставляемые базовой библиотекой C операционной системы. Эти локали используются большинством системных инструментов. Другим источником является icu, который задействует внешнюю библиотеку ICU. Локали ICU можно использовать только в том случае, если поддержка ICU была включена при сборке PostgreSQL.

Инструменты и команды для выбора настроек локализации, описанные выше, позволяют выбрать поставщика локалей. Приведенные ранее примеры использовали провайдера libc, который является стандартным. Вот пример инициализации кластера баз данных с провайдером ICU:

initdb --locale-provider=icu --icu-locale=en

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

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

Проблемы

Если поддержка локалей работает неправильно, проверьте правильность настройки локалей в операционной системе. Узнать, какие локали установлены в системе, можно с помощью команды locale -a, если ОС ее поддерживает.

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

Исходники PostgreSQL содержат тестовый набор для проверки поддержки локалей в каталоге src/test/locale.

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

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