22.3. Support des jeux de caractères

Le support des jeux de caractères dans PostgreSQL™ permet d'insérer du texte dans différents jeux de caractères (aussi appelés encodages), dont ceux mono-octet tels que la série ISO 8859 et ceux multi-octets tels que EUC (Extended Unix Code), UTF-8 ou le codage interne Mule. Tous les jeux de caractères supportés peuvent être utilisés de façon transparente par les clients mais certains ne sont pas supportés par le serveur (c'est-à-dire comme encodage du serveur). Le jeu de caractères par défaut est sélectionné pendant l'initialisation du cluster de base de données avec initdb. Ce choix peut être surchargé à la création de la base. Il est donc possible de disposer de bases utilisant chacune un jeu de caractères différent.

Il existe, cependant une importante restriction : le jeu de caractère de la base de données doit être compatible avec les variables d'environnement LC_CTYPE (classification des caractères) et LC_COLLATE (ordre de tri des chaînes) de la base de données. Pour les locales C ou POSIX, tous les jeux de caractères sont autorisés, mais pour les locales, il n'y a qu'un seul jeux de caractères qui fonctionne correctement. (Néanmoins, sur Windows, l'encodage UTF-8 peut être utilisé avec toute locale.)

22.3.1. Jeux de caractères supportés

Le Tableau 22.1, « Jeux de caractères de PostgreSQL™ » présente les jeux de caractères utilisables avec PostgreSQL™.

Tableau 22.1. Jeux de caractères de PostgreSQL

Nom Description Langue Serveur ? Octets/Caractère Alias
BIG5 Big Five Chinois traditionnel Non 1-2 WIN950, Windows950
EUC_CN Code-CN Unix étendu Chinois simplifié Oui 1-3  
EUC_JP Code-JP Unix étendu Japonais Oui 1-3  
EUC_JIS_2004 Code-JP Unix étendu, JIS X 0213 Japonais Oui 1-3  
EUC_KR Code-KR Unix étendu Coréen Oui 1-3  
EUC_TW Code-TW Unix étendu Chinois traditionnel, taïwanais Oui 1-3  
GB18030 Standard national Chinois Non 1-4  
GBK Standard national étendu Chinois simplifié Non 1-2 WIN936, Windows936
ISO_8859_5 ISO 8859-5, ECMA 113 Latin/Cyrillique Oui 1  
ISO_8859_6 ISO 8859-6, ECMA 114 Latin/Arabe Oui 1  
ISO_8859_7 ISO 8859-7, ECMA 118 Latin/Grec Oui 1  
ISO_8859_8 ISO 8859-8, ECMA 121 Latin/Hébreu Oui 1  
JOHAB JOHAB Koréen (Hangul) Non 1-3  
KOI8 KOI8-R(U) Cyrillique Oui 1 KOI8R
KOI8R KOI8-R Cyrillique (Russie) Oui 1 KOI8
KOI8U KOI8-U Cyrillique (Ukraine) Oui 1  
LATIN1 ISO 8859-1, ECMA 94 Europe de l'ouest Oui 1 ISO88591
LATIN2 ISO 8859-2, ECMA 94 Europe centrale Oui 1 ISO88592
LATIN3 ISO 8859-3, ECMA 94 Europe du sud Oui 1 ISO88593
LATIN4 ISO 8859-4, ECMA 94 Europe du nord Oui 1 ISO88594
LATIN5 ISO 8859-9, ECMA 128 Turque Oui 1 ISO88599
LATIN6 ISO 8859-10, ECMA 144 Nordique Oui 1 ISO885910
LATIN7 ISO 8859-13 Baltique Oui 1 ISO885913
LATIN8 ISO 8859-14 Celtique Oui 1 ISO885914
LATIN9 ISO 8859-15 ISO885915 avec l'Euro et les accents Oui 1 ISO885915
LATIN10 ISO 8859-16, ASRO SR 14111 Roumain Oui 1 ISO885916
MULE_INTERNAL Code interne Mule Emacs multi-langues Oui 1-4  
SJIS Shift JIS Japonais Non 1-2 Mskanji, ShiftJIS, WIN932, Windows932
SHIFT_JIS_2004 Shift JIS, JIS X 0213 Japonais Non 1-2  
SQL_ASCII non spécifié (voir le texte) tout Oui 1  
UHC Code unifié Hangul Koréen Non 1-2 WIN949, Windows949
UTF8 Unicode, 8-bit tous Oui 1-4 Unicode
WIN866 Windows CP866 Cyrillique Oui 1 ALT
WIN874 Windows CP874 Thai Oui 1  
WIN1250 Windows CP1250 Europe centrale Oui 1  
WIN1251 Windows CP1251 Cyrillique Oui 1 WIN
WIN1252 Windows CP1252 Europe de l'ouest Oui 1  
WIN1253 Windows CP1253 Grec Oui 1  
WIN1254 Windows CP1254 Turque Oui 1  
WIN1255 Windows CP1255 Hébreux Oui 1  
WIN1256 Windows CP1256 Arabe Oui 1  
WIN1257 Windows CP1257 Baltique Oui 1  
WIN1258 Windows CP1258 Vietnamien Oui 1 ABC, TCVN, TCVN5712, VSCII

Toutes les API clients ne supportent pas tous les jeux de caractères de la liste. Le pilote JDBC de PostgreSQL™, par exemple, ne supporte pas MULE_INTERNAL, LATIN6, LATIN8 et LATIN10.

SQL_ASCII se comporte de façon considérablement différente des autres valeurs. Quand le jeu de caractères du serveur est SQL_ASCII, le serveur interprète les valeurs des octets 0-127 suivant le standard ASCII alors que les valeurs d'octets 128-255 sont considérées comme des caractères non interprétés. Aucune conversion de codage n'est effectuée avec SQL_ASCII. De ce fait, cette valeur ne déclare pas tant un encodage spécifique que l'ignorance de l'encodage. Dans la plupart des cas, si des données non ASCII doivent être traitées, il est déconseillé d'utiliser la valeur SQL_ASCII car PostgreSQL™ est alors incapable de convertir ou de valider les caractères non ASCII.

22.3.2. Choisir le jeu de caractères

initdb définit le jeu de caractères par défaut (encodage) pour un cluster. Par exemple,

initdb -E EUC_JP

paramètre le jeu de caractères à EUC_JP (Extended Unix Code for Japanese). L'option --encoding peut aussi être utilisée à la place de -E (options longues). Si aucune option -E ou --encoding n'est donnée, initdb tente de déterminer l'encodage approprié en fonction de la locale indiquée ou de celle par défaut.

Vous pouvez indiquer un encodage autre que celui par défaut lors de la création de la base de données, à condition que l'encodage soit compatible avec la locale sélectionnée :

createdb -E EUC_KR -T template0 --lc-collate=ko_KR.euckr --lc-ctype=ko_KR.euckr korean

Cela crée une base de données appelée korean qui utilise le jeu de caractères EUC_KR, et la locale ko_KR. Un autre moyen de réaliser cela est d'utiliser la commande SQL suivante :

CREATE DATABASE korean WITH ENCODING 'EUC_KR' LC_COLLATE='ko_KR.euckr' LC_CTYPE='ko_KR.euckr' TEMPLATE=template0;
    

Notez que les commandes ci-dessus précisent de copier la base de données template0. Lors de la copie d'une autre base, les paramètres d'encodage et de locale ne peuvent pas être modifiés de ceux de la base de données source car cela pourrait corrompre les données. Pour plus d'informations, voir Section 21.3, « Bases de données modèles ».

L'encodage de la base de données est conservé dans le catalogue système pg_database. Cela est visible à l'aide de l'option -l ou de la commande \l de psql.

$ 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)
[Important]

Important

Sur la plupart des systèmes d'exploitation modernes, PostgreSQL™ peut déterminer le jeu de caractères impliqué par la variable LC_CTYPE, et s'assure que l'encodage correspondant de la base de données est utilisé. Sur les systèmes plus anciens, il est de la responsabilité de l'utilisateur de s'assurer que l'encodage attendu par la locale est bien utilisé. Une erreur à ce niveau risque fort de conduire à un comportement étrange des opérations liées à la locale, tel le tri.

PostgreSQL™ autorise les superutilisateurs à créer des bases de données avec le jeu de caractère SQL_ASCII même lorsque la variable LC_CTYPE n'est pas à C ou POSIX. Comme indiqué plus haut, SQL_ASCII n'impose aucun encodage particulier aux données stockées en base, ce qui rend ce paramétrage vulnérable aux comportements erratiques lors d'opérations liées à la locale. Cette combinaison de paramètres est dépréciée et pourrait un jour être interdite.

22.3.3. Conversion automatique d'encodage entre serveur et client

PostgreSQL™ automatise la conversion de jeux de caractères entre client et serveur pour certaines combinaisons de jeux de caractères. Les informations de conversion sont conservées dans le catalogue système pg_conversion. PostgreSQL™ est livré avec certaines conversions prédéfinies, conversions listées dans le Tableau 22.2, « Conversion de jeux de caractères client/serveur ». Une nouvelle conversion peut être créée en utilisant la commande SQL CREATE CONVERSION.

Tableau 22.2. Conversion de jeux de caractères client/serveur

Jeu de caractères serveur Jeux de caractères client disponibles
BIG5 non supporté comme encodage serveur
EUC_CN EUC_CN, MULE_INTERNAL, UTF8
EUC_JP EUC_JP, MULE_INTERNAL, SJIS, UTF8
EUC_KR EUC_KR, MULE_INTERNAL, UTF8
EUC_TW EUC_TW, BIG5, MULE_INTERNAL, UTF8
GB18030 non supporté comme encodage serveur
GBK non supporté comme encodage serveur
ISO_8859_5 ISO_8859_5, KOI8R, MULE_INTERNAL, UTF8, WIN866, WIN1251
ISO_8859_6 ISO_8859_6, UTF8
ISO_8859_7 ISO_8859_7, UTF8
ISO_8859_8 ISO_8859_8, UTF8
JOHAB JOHAB, UTF8
KOI8R KOI8R, ISO_8859_5, MULE_INTERNAL, UTF8, WIN866, WIN1251
KOI8U KOI8U, UTF8
LATIN1 LATIN1, MULE_INTERNAL, UTF8
LATIN2 LATIN2, MULE_INTERNAL, UTF8, WIN1250
LATIN3 LATIN3, MULE_INTERNAL, UTF8
LATIN4 LATIN4, MULE_INTERNAL, UTF8
LATIN5 LATIN5, UTF8
LATIN6 LATIN6, UTF8
LATIN7 LATIN7, UTF8
LATIN8 LATIN8, UTF8
LATIN9 LATIN9, UTF8
LATIN10 LATIN10, UTF8
MULE_INTERNAL MULE_INTERNAL, BIG5, EUC_CN, EUC_JP, EUC_KR, EUC_TW, ISO_8859_5, KOI8R, LATIN1 vers LATIN4, SJIS, WIN866, WIN1250, WIN1251
SJIS non supporté comme encodage serveur
SQL_ASCII tous (aucune conversion n'est réalisée)
UHC non supporté comme encodage serveur
UTF8 tout encodage supporté
WIN866 WIN866, ISO_8859_5, KOI8R, MULE_INTERNAL, UTF8, WIN1251
WIN874 WIN874, UTF8
WIN1250 WIN1250, LATIN2, MULE_INTERNAL, UTF8
WIN1251 WIN1251, ISO_8859_5, KOI8R, MULE_INTERNAL, UTF8, WIN866
WIN1252 WIN1252, UTF8
WIN1253 WIN1253, UTF8
WIN1254 WIN1254, UTF8
WIN1255 WIN1255, UTF8
WIN1256 WIN1256, UTF8
WIN1257 WIN1257, UTF8
WIN1258 WIN1258, UTF8

Pour activer la conversion automatique des jeux de caractères, il est nécessaire d'indiquer à PostgreSQL™ le jeu de caractères (encodage) souhaité côté client. Il y a plusieurs façons de le faire :

  • en utilisant la commande \encoding dans psql. \encoding permet de changer l'encodage client à la volée. Par exemple, pour changer le codage en SJIS, taper :

    \encoding SJIS
    
  • la libpq (Section 31.10, « Fonctions de contrôle ») a des fonctions de contrôle de l'encodage client ;

  • en utilisant SET client_encoding TO. L'encodage client peut être fixé avec la commande SQL suivante :

    SET CLIENT_ENCODING TO 'valeur';
    

    La syntaxe SQL plus standard SET NAMES peut également être utilisée pour cela :

    SET NAMES 'valeur';
    

    Pour connaître l'encodage client courant :

    SHOW client_encoding;
    

    Pour revenir à l'encodage par défaut :

    RESET client_encoding;
    
  • en utilisant PGCLIENTENCODING. Si la variable d'environnement PGCLIENTENCODING est définie dans l'environnement client, l'encodage client est automatiquement sélectionné lors de l'établissement d'une connexion au serveur (cette variable peut être surchargée à l'aide de toute autre méthode décrite ci-dessus) ;

  • en utilisant la variable de configuration client_encoding. Si la variable client_encoding est définie, l'encodage client est automatiquement sélectionné lors de l'établissement d'une connexion au serveur (cette variable peut être surchargée à l'aide de toute autre méthode décrite ci-dessus).

Si la conversion d'un caractère particulier n'est pas possible -- dans le cas d'encodages EUC_JP pour le serveur et LATIN1 pour le client, et que certains caractères japonais renvoyés n'ont pas de représentation en LATIN1 -- une erreur est remontée.

Si l'encodage client est défini en tant que SQL_ASCII, la conversion de l'encodage est désactivée quelque soit celui du serveur. Comme pour le serveur, SQL_ASCII est déconseillé sauf à ne travailler qu'avec des données ASCII.

22.3.4. Pour aller plus loin

Il existe quelques sources intéressantes pour commencer à maîtriser les différents jeux de caractères.

CJKV Information Processing: Chinese, Japanese, Korean & Vietnamese Computing

Contient des explications détaillées de EUC_JP, EUC_CN, EUC_KR, EUC_TW.

http://www.unicode.org/

Le site web du Unicode Consortium.

RFC 3629

UTF-8 (8-bit UCS/Unicode Transformation Format) est défini ici.