Protože svět by byl nudný, pokud by byl jednoduchý, již od pradávna si lidé a nejen lidé vymýšlejí různé způsoby, jak si ten život alespoň trošku zpestřit nebo i zkomplikovat. Různost jazyků a způsobů, jak zapisovat v té které části světa slova, je toho dokladem, a v případě snahy přenést a vyřešit tento problém u software jsou toho dokladem i vrásky na tvářích programátoru a uživatelů.
Snahou vývojářů PostgreSQL je, aby vrásek na tváři uživatelů v různých částech světa bylo co nejméně. Pro začátek bude dobré si ozřejmit dva základní pojmy, a to „locale“ a „encoding“.
Tedy „locale“. Často hovoříme o tom, že nějaký program má podporu locale. Znamená to, že daný program umí v přesně definovaných kategoriích pracovat s daty tak, jak je to pro daný stát (oblast) běžné. Těmito kategoriemi jsou:
LC_COLLATE |
porovnávání řetězců |
PostgreSQL nevyužívá v současné době všechny tyto kategorie, ale pouze LC_COLLATE, LC_CTYPE, LC_MONETARY. Malou výjimkou jsou funkce to_char() a to_number(), které jsou schopny využívat i typ LC_NUMERIC (v budoucnu možná i LC_TIME). Od verze 7.2 je používán i LC_MESSAGES.
To znamená, že například standardní výstup čísla bude vždy ve formátu s tečkou na místě desetinné čárky. Podobně i čas a datum budou vždy používat anglická jména dní a měsíců. Toto omezení snad bude v některých budoucích verzích řešeno (locale-per-column). Prozatím můžete v případě čísel použít funkci to_char().
K tomu, aby PostgreSQL mohl používal locale, musí být kompilován s jejich podporou (–enable-locale). Je možné, že takto připravený server je součástí i vaší oblíbené distribuce.
Teď mírně přeskočíme a podíváme se na „encoding“, tedy kódování. Masochismus některých lidí okolo počítačů neznal mezí, a proto dnes máme často i pro jeden jazyk několik různých kódování. Čeština není výjimkou, ba dokonce je zářným příkladem. Naštěstí se dnes doba ustálila na dvou základních, a to ISO-8859–2 (alias Latin2), které je mezinárodně potvrzeným standardem, a tím druhým kódováním je Win1250, což je mezinárodně trpěný nestandard firmy Microsoft.
Novější řešení v oblasti kódování je UNICODE, multibyte kódování, které je schopno obsáhnout v sobě všechny myslitelné znaky.
PostgreSQL podporuje všechna tato jmenovaná kódování. Pochopitelné obsahuje i podporu dalších, ve verzi 7.2 jsou to:
Alt (IBM866), BIG5, EUC-CN, EUC_JP, EUC_KR, EUC_TW, ISO-8859–1, ISO-8859–2, ISO-8859–3, ISO-8859–4, ISO-8859–5, ISO-8859–6, ISO-8859–7, ISO-8859–8, ISO-8859–9, ISO-8859–10, ISO-8859–13, ISO-8859–14, ISO-8859–15, ISO-8859–16, KOI8-R, Shift-JIS, UTF-8, WIN1250, WIN1251, SQL_ASCII a MULE_INTERNAL,
Jen pro doplnění a případné zvědavce, „MULE_INTERNAL“ je vlastní PostgreSQL multibyte kódování, které lze používat například namísto UNICODE. Jedná se o historickou záležitost.
Důležité je poznamenat, že PostgreSQL poněkud neštastně používá pro jména kódování aliasy, například LATIN2. Od připravované verze 7.2 bude možné pro jména kódování používat i standardních názvů (např. ISO-8859–2).
Proto, aby PostgreSQL byl schopen využívat různá kódování, je nutné ho kompilovat s přepínačem –enable-multibyte –enable-recode.
Předpokládejme, že již máte PostgreSQL s podporou jak různých kódování, tak locale, a že máte server standardně nainstalovaný.
A teď to nejdůležitější, což je inicializace prostoru, kde budou uloženy databáze. V případě, že za vás tuto inicializaci provádí nějaký instalační systém (deb, rpm), je vhodné se přesvědčit o tom, jak byla inicializace provedena (podle mne by to mělo být u solidního balíčku dané distribuce popsáno). Pochopitelně tuto inicializaci lze provést i dodatečně a třeba i několikrát, ovšem za podmínky, že vaše databáze neobsahují data.
Inicializace prostoru pro databáze (database cluster) se provádí programem „initdb“. Program musí být spuštěn pod uživatelem, pod kterým při běžném použití poběží SQL server.
Locale se nastavují pouze a jen při této inicializaci. Je to proto, že za chodu lze velmi těžko měnit věci, které mají fatální vliv na záležitosti, jako jsou indexy. To znamená, že máte-li inicializaci provedenou s en_US, je pozdější laborování s cs_CZ naprosto zbytečné. Příklad:
# su - postgres $ export LANG="czech" $ /usr/local/postgresql/bin/initdb -D /var/postgresql
Tento příklad připraví v adresáři /var/postgresql prostor pro databáze s tím, že se předpokládá použití českých locale.
Při inicializaci lze taktéž definovat implicitní kódování databází, a to pomocí parametru -E (například -E LATIN2). Každá nově vytvořená databáze, není-li specifikováno jinak, pak bude používat toto kódování.
Nyní již máme server kompletně připraven k použítí. Tiše předpokládám, že jste se podívali do dokumentace na to, jak si udělat uživatele (su – postgres; createuser někdo). Stejně tak předpokládám, že jste se vyrovnali s tím, jak donutit server používat TCP/IP (start s parametrem -i). Dobré je v konfiguraci nebo startujících skriptech zohlednit vámi požadované nastavení locale (export LANG=czech), záleží to na vaší distribuci a na způsobu, jakým startuje PostgreSQL server.
A nyní hurá do používání. Server nám běží a je tedy na čase udělat si nějakou tu databázi. Na počátku je dobré použít služeb skriptu createdb. Opět zde lze specifikovat kódování, ve kterém má databáze být (parametr -E). Není-li kódování specifikováno, použije se defaultní, které jste specifikovali při inicializaci pomocí skriptu initdb. Pokud jste ani zde žádné kódování nenastavili, bude databáze vytvořena v kódování SQL_ASCII.
PostgreSQL pochopitelně umožňuje používat databáze v různých kódováních. Společným pro všechny databáze je jen nastavení locale.
Nyní se můžeme k naší databázi přihlásit. PostgreSQL umožňuje jednu důležitou věc, a to rozdílné kódování databáze a klienta. Znamená to, že data jsou v obou směrech serverem překódovávána. Pochopitelně, že k tomu, aby server takové překódování prováděl, potřebuje informaci, co daný klient používá. Tu mu lze poskytnout dvěma způsoby. Buď ještě před startem klienta nastavíme proměnnou PGCLIENTENCODING=LATIN2 (nebo jiné kódování), a nebo za běhu klienta provedeme SQL příkaz SET CLIENT_ENCODING TO ‚LATIN2‘;.
V případě, že serveru nesdělíte, v jakém kódování pracuje klient, bude předpokládat, že se jedná o stejné kódování, jako používá databáze, ke které se klient připojil.
A nyní je naše session s PostgreSQL serverem plně připravena a můžete do serveru vkládat data v daném kódování.
Kontrolu nastavení lze provést příkazy: SHOW CLIENT_ENCODING; a SHOW SERVER_ENCODING;. V klientském programu „psql“ pak lze pomocí příkazu \l zobrazit seznam všech databází včetně používaného kódování. Například:
Name | Owner | Encoding --------------+----------+----------- il2 | zakkr | LATIN2 mape_catalog | mape | SQL_ASCII utf | nooper | UNICODE template0 | postgres | SQL_ASCII template1 | postgres | SQL_ASCII (5 rows)
Z vlastní zkušenosti mohu potvrdit i to, že v jedné databázi (s UNICODE) lze mít texty v několika různých jazycích reprezentovaných na straně klienta různými kódováními. Práce s takovou DB je záležitostí pečlivého odlišení jazyka jednotlivých textů a následného adekvátního nastavování CLIENT_ENCODING. To může být efektivní například u web aplikace, která pracuje v různých jazycích.
Pro úplnost ještě poznamenám, že ve spojitosti s kódováním lze použít funkci to_ascii(), která provede překódování do ASCII. Od verze 7.2 bude dostupná další funkce, a to je convert(), umožňující převod z jednoho kódování do druhého.
Nechť vám příliš žluťoučký kůň úpí ďábelské (k)ódy i v PostgreSQL.