julik live

Unicode и PostgreSQL

Эта часть Unicode-эпопепеи будет довольно короткой.


В PostgreSQL изначально существуют (еще с тех времен когда MySQL версии 3.22 в этом плане под стол пешком ходил) следующие понятия:

  • Кодировка кластера
  • Кодировка базы данных
  • Кодировка клиента

Само собой кодировка базы имеет над кодировкой кластера преимущество. Кодировка клиента задается запросом SET ENCODING “encoding_name”. Нужное нам имя - UNICODE. При создании базы (или кластера) оную кодировку нужно указать явно, на всякий случай.

Подводный камень здесь есть, и о нем мало кто знает. В PostgreSQL на самом деле встроена большая часть функциональности локалей, но при сборке Postgres (в доках написано совсем другое) по умлочанию цепляется к системным локалям - а это значит, что для корректной работы в UTF локаль и пользователя, под которым работает postmsater, и пользователя, который с базой соединяется, должна быть UTF-8. Это никуда не годится. Посему цитирую письмо человека, ответственного за всю поддержку кодировок в PostgreSQL, а вы уж делайте выводы:

    From:  t-ishii@sra.co.jp
    Subject: Re: Encoding support in PostgreSQL
    Date: некая дата мохнатой давности
    To: julik@...

    <skipped>

    That's because you did not run initdb with “--no-locale”. I have been
    troubled by the locale support too since the day one when it's enabled
    by default. Don't ask me why it's enabled by default since I don't
    know why.

    <skipped>

    2) What is the encoding of your cluster

    default to SQL_ASCII unless you specify different encoding with -E
    option.

    3) What is the encoding of your database

    default to the cluster encoding unless you give -E option to createdb.

    4) What is the encoding of your client

    default to the database encoding

    As of 7.3.4 the locale support is always compiled in. The only way to
    disable the locale support is the initdb time. Use --no-locale option
    with initdb.

initdb - команда создания кластера. Здесь уж, как говорится, флаг в руки (хостер скорее всего кластер для вас перестраивать не будет, но после его отказа можете опять же сослать его на данную статью). Кстати, если есть действительно “странные” вопросы по кодировкам в PostgreSQL, пишите этому человеку. Он за них в ответе.

Да, в версиях PostgreSQL до 8 в UTF не работает конверсия регистра (то бишь ILIKE, lower() и upper()). Что невероятно огорчительно но поделать с этим, увы, ничего нельзя - ставьте восьмую версию.

Вкратце же юникодный Postgres-кластер создается так:

  • Собирается PostgreSQL
  • Пользователю postmaster (или другому пользователю, от имени которого будет работать демон postmaster), выставляется локаль UTF - export LANG ru_RU.UTF-8 и export LC_COLLATE=ru.
  • Создается кластер - initdb /mycluster ---encoding UNICODE
  • Создается база - CREATE DATABASE my_db WITH ENCODING UNICODE

И еще -- при работе с юникодом безопаснее пользоваться “проприетарными” (бинарными) дампами Postgres.

Проблем при работе с юникодными базами из Java и PHP я не замечал. При работе из ODBC-драйвера проблемы будут в любом случае (хоть в EUC-KR).

Suspects: Веб-стройка Юникод

 
comments powered by Disqus

Aspirine not included.