PostgreSQLLa base de données la plus sophistiquée au monde.
Documentation PostgreSQL 13.0 » Administration du serveur » Localisation » Support des jeux de caractères

23.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 provenant de la libc, 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.) Si le support d'ICU est configuré, les locales fournies par ICU peuvent être utilisées avec la plupart des encodages côté serveur.

23.3.1. Jeux de caractères supportés

Le Tableau 23.1 présente les jeux de caractères utilisables avec PostgreSQL.

Tableau 23.1. Jeux de caractères de PostgreSQL

NomDescriptionLangueServeur ?ICU ?Octets/​CaractèreAlias
BIG5Big FiveChinois traditionnelNonNon1–2WIN950, Windows950
EUC_CNCode-CN Unix étenduChinois simplifiéOuiOui1–3 
EUC_JPCode-JP Unix étenduJaponaisOuiOui1–3 
EUC_JIS_2004Code-JP Unix étendu, JIS X 0213JaponaisOuiNon1–3 
EUC_JIS_2004EUC_JIS_2004, SHIFT_JIS_2004, UTF8      
EUC_KRCode-KR Unix étenduCoréenOuiOui1–3 
EUC_TWCode-TW Unix étenduChinois traditionnel, taïwanaisOuiOui1–3 
GB18030Standard nationalChinoisNonNon1–4 
GBKStandard national étenduChinois simplifiéNonNon1–2WIN936, Windows936
ISO_8859_5ISO 8859-5, ECMA 113Latin/CyrilliqueOuiOui1 
ISO_8859_6ISO 8859-6, ECMA 114Latin/ArabeOuiOui1 
ISO_8859_7ISO 8859-7, ECMA 118Latin/GrecOuiOui1 
ISO_8859_8ISO 8859-8, ECMA 121Latin/HébreuOuiOui1 
JOHABJOHABCoréen (Hangul)NonNon1-3 
KOI8KOI8-R(U)CyrilliqueOuiOui1KOI8R
KOI8RKOI8-RCyrillique (Russie)OuiOui1KOI8
KOI8UKOI8-UCyrillique (Ukraine)OuiOui1 
LATIN1ISO 8859-1, ECMA 94Europe de l'ouestOuiOui1ISO88591
LATIN2ISO 8859-2, ECMA 94Europe centraleOuiOui1ISO88592
LATIN3ISO 8859-3, ECMA 94Europe du sudOuiOui1ISO88593
LATIN4ISO 8859-4, ECMA 94Europe du nordOuiOui1ISO88594
LATIN5ISO 8859-9, ECMA 128TurqueOuiOui1ISO88599
LATIN6ISO 8859-10, ECMA 144NordiqueOuiOui1ISO885910
LATIN7ISO 8859-13BaltiqueOuiOui1ISO885913
LATIN8ISO 8859-14CeltiqueOuiOui1ISO885914
LATIN9ISO 8859-15ISO885915 avec l'Euro et les accentsOuiOui1ISO885915
LATIN10ISO 8859-16, ASRO SR 14111RoumainOuiNon1ISO885916
MULE_INTERNALCode interne MuleEmacs multi-languesOuiNon1–4 
SJISShift JISJaponaisNonNon1–2Mskanji, ShiftJIS, WIN932, Windows932
SHIFT_JIS_2004Shift JIS, JIS X 0213JaponaisNonNon1–2 
SQL_ASCIInon spécifié (voir le texte)toutOuiNon1 
UHCCode unifié HangulCoréenNonNon1–2WIN949, Windows949
UTF8Unicode, 8-bittousOuiOui1–4Unicode
WIN866Windows CP866CyrilliqueOuiOui1ALT
WIN874Windows CP874ThaiOuiNon1 
WIN1250Windows CP1250Europe centraleOuiOui1 
WIN1251Windows CP1251CyrilliqueOuiOui1WIN
WIN1252Windows CP1252Europe de l'ouestOuiOui1 
WIN1253Windows CP1253GrecOuiOui1 
WIN1254Windows CP1254TurqueOuiOui1 
WIN1255Windows CP1255HébreuxOuiOui1 
WIN1256Windows CP1256ArabeOuiOui1 
WIN1257Windows CP1257BaltiqueOuiOui1 
WIN1258Windows CP1258VietnamienOuiOui1ABC, 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.

23.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 (option longue) peut aussi être utilisée à la place de -E. 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 22.3.

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

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'assurer 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.

23.3.3. Conversion automatique d'encodage entre serveur et client

PostgreSQL automatise la conversion de jeux de caractères entre client et serveur pour un grand nombre de combinaisons de jeux de caractères (Section 23.3.4 montre lesquels).

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 33.10) 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. (Toutefois, si l'encodage serveur n'est pas SQL_ASCII, le serveur testera toujours que les données en entrée sont valides pour cet encodage ; le résultat final est identique à si l'encodage client était le même que celui du serveur). Comme pour le serveur, SQL_ASCII est déconseillé sauf à ne travailler qu'avec des données ASCII.

23.3.4. Conversions disponibles entre jeux de caractères

PostgreSQL permet les conversions entre deux jeux de caractères quand une fonction de conversion est listée dans le catalogue système pg_conversion. PostgreSQL est fourni avec des conversions prédéfinies, comme résumé dans Tableau 23.2 et détaillé dans Tableau 23.3. On peut créer une nouvelle conversion en utilisant la commande SQL CREATE CONVERSION. (Pour être utilisée pour les conversions client/serveur automatiques, une conversion doit être marquée en tant que « default » pour son couple de jeux de caractères).

Tableau 23.2. Conversions client/serveur fournies de base pour les jeux de caractères

Jeux de caractères sur le serveurJeux de caractères disponibles sur le client
BIG5non supporté comme encodage serveur
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
GB18030non supporté comme encodage serveur
GBKnon supporté comme encodage serveur
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
JOHABnon supporté comme encodage serveur
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
LATIN5LATIN5, 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 to LATIN4, SJIS, WIN866, WIN1250, WIN1251
SJISnon supporté comme encodage serveur
SHIFT_JIS_2004non supporté comme encodage serveur
SQL_ASCIIany (no conversion will be performed)
UHCnon supporté comme encodage serveur
UTF8tous les encodages supportés
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

Tableau 23.3. Toutes les conversions fournies de base entre jeux de caractères

Nom de la conversion [a] Encodage sourceEncodage de destination
big5_to_euc_twBIG5EUC_TW
big5_to_micBIG5MULE_INTERNAL
big5_to_utf8BIG5UTF8
euc_cn_to_micEUC_CNMULE_INTERNAL
euc_cn_to_utf8EUC_CNUTF8
euc_jp_to_micEUC_JPMULE_INTERNAL
euc_jp_to_sjisEUC_JPSJIS
euc_jp_to_utf8EUC_JPUTF8
euc_kr_to_micEUC_KRMULE_INTERNAL
euc_kr_to_utf8EUC_KRUTF8
euc_tw_to_big5EUC_TWBIG5
euc_tw_to_micEUC_TWMULE_INTERNAL
euc_tw_to_utf8EUC_TWUTF8
gb18030_to_utf8GB18030UTF8
gbk_to_utf8GBKUTF8
iso_8859_10_to_utf8LATIN6UTF8
iso_8859_13_to_utf8LATIN7UTF8
iso_8859_14_to_utf8LATIN8UTF8
iso_8859_15_to_utf8LATIN9UTF8
iso_8859_16_to_utf8LATIN10UTF8
iso_8859_1_to_micLATIN1MULE_INTERNAL
iso_8859_1_to_utf8LATIN1UTF8
iso_8859_2_to_micLATIN2MULE_INTERNAL
iso_8859_2_to_utf8LATIN2UTF8
iso_8859_2_to_windows_1250LATIN2WIN1250
iso_8859_3_to_micLATIN3MULE_INTERNAL
iso_8859_3_to_utf8LATIN3UTF8
iso_8859_4_to_micLATIN4MULE_INTERNAL
iso_8859_4_to_utf8LATIN4UTF8
iso_8859_5_to_koi8_rISO_8859_5KOI8R
iso_8859_5_to_micISO_8859_5MULE_INTERNAL
iso_8859_5_to_utf8ISO_8859_5UTF8
iso_8859_5_to_windows_1251ISO_8859_5WIN1251
iso_8859_5_to_windows_866ISO_8859_5WIN866
iso_8859_6_to_utf8ISO_8859_6UTF8
iso_8859_7_to_utf8ISO_8859_7UTF8
iso_8859_8_to_utf8ISO_8859_8UTF8
iso_8859_9_to_utf8LATIN5UTF8
johab_to_utf8JOHABUTF8
koi8_r_to_iso_8859_5KOI8RISO_8859_5
koi8_r_to_micKOI8RMULE_INTERNAL
koi8_r_to_utf8KOI8RUTF8
koi8_r_to_windows_1251KOI8RWIN1251
koi8_r_to_windows_866KOI8RWIN866
koi8_u_to_utf8KOI8UUTF8
mic_to_big5MULE_INTERNALBIG5
mic_to_euc_cnMULE_INTERNALEUC_CN
mic_to_euc_jpMULE_INTERNALEUC_JP
mic_to_euc_krMULE_INTERNALEUC_KR
mic_to_euc_twMULE_INTERNALEUC_TW
mic_to_iso_8859_1MULE_INTERNALLATIN1
mic_to_iso_8859_2MULE_INTERNALLATIN2
mic_to_iso_8859_3MULE_INTERNALLATIN3
mic_to_iso_8859_4MULE_INTERNALLATIN4
mic_to_iso_8859_5MULE_INTERNALISO_8859_5
mic_to_koi8_rMULE_INTERNALKOI8R
mic_to_sjisMULE_INTERNALSJIS
mic_to_windows_1250MULE_INTERNALWIN1250
mic_to_windows_1251MULE_INTERNALWIN1251
mic_to_windows_866MULE_INTERNALWIN866
sjis_to_euc_jpSJISEUC_JP
sjis_to_micSJISMULE_INTERNAL
sjis_to_utf8SJISUTF8
windows_1258_to_utf8WIN1258UTF8
uhc_to_utf8UHCUTF8
utf8_to_big5UTF8BIG5
utf8_to_euc_cnUTF8EUC_CN
utf8_to_euc_jpUTF8EUC_JP
utf8_to_euc_krUTF8EUC_KR
utf8_to_euc_twUTF8EUC_TW
utf8_to_gb18030UTF8GB18030
utf8_to_gbkUTF8GBK
utf8_to_iso_8859_1UTF8LATIN1
utf8_to_iso_8859_10UTF8LATIN6
utf8_to_iso_8859_13UTF8LATIN7
utf8_to_iso_8859_14UTF8LATIN8
utf8_to_iso_8859_15UTF8LATIN9
utf8_to_iso_8859_16UTF8LATIN10
utf8_to_iso_8859_2UTF8LATIN2
utf8_to_iso_8859_3UTF8LATIN3
utf8_to_iso_8859_4UTF8LATIN4
utf8_to_iso_8859_5UTF8ISO_8859_5
utf8_to_iso_8859_6UTF8ISO_8859_6
utf8_to_iso_8859_7UTF8ISO_8859_7
utf8_to_iso_8859_8UTF8ISO_8859_8
utf8_to_iso_8859_9UTF8LATIN5
utf8_to_johabUTF8JOHAB
utf8_to_koi8_rUTF8KOI8R
utf8_to_koi8_uUTF8KOI8U
utf8_to_sjisUTF8SJIS
utf8_to_windows_1258UTF8WIN1258
utf8_to_uhcUTF8UHC
utf8_to_windows_1250UTF8WIN1250
utf8_to_windows_1251UTF8WIN1251
utf8_to_windows_1252UTF8WIN1252
utf8_to_windows_1253UTF8WIN1253
utf8_to_windows_1254UTF8WIN1254
utf8_to_windows_1255UTF8WIN1255
utf8_to_windows_1256UTF8WIN1256
utf8_to_windows_1257UTF8WIN1257
utf8_to_windows_866UTF8WIN866
utf8_to_windows_874UTF8WIN874
windows_1250_to_iso_8859_2WIN1250LATIN2
windows_1250_to_micWIN1250MULE_INTERNAL
windows_1250_to_utf8WIN1250UTF8
windows_1251_to_iso_8859_5WIN1251ISO_8859_5
windows_1251_to_koi8_rWIN1251KOI8R
windows_1251_to_micWIN1251MULE_INTERNAL
windows_1251_to_utf8WIN1251UTF8
windows_1251_to_windows_866WIN1251WIN866
windows_1252_to_utf8WIN1252UTF8
windows_1256_to_utf8WIN1256UTF8
windows_866_to_iso_8859_5WIN866ISO_8859_5
windows_866_to_koi8_rWIN866KOI8R
windows_866_to_micWIN866MULE_INTERNAL
windows_866_to_utf8WIN866UTF8
windows_866_to_windows_1251WIN866WIN
windows_874_to_utf8WIN874UTF8
euc_jis_2004_to_utf8EUC_JIS_2004UTF8
utf8_to_euc_jis_2004UTF8EUC_JIS_2004
shift_jis_2004_to_utf8SHIFT_JIS_2004UTF8
utf8_to_shift_jis_2004UTF8SHIFT_JIS_2004
euc_jis_2004_to_shift_jis_2004EUC_JIS_2004SHIFT_JIS_2004
shift_jis_2004_to_euc_jis_2004SHIFT_JIS_2004EUC_JIS_2004

[a] Les noms des conversions suivent un standard de nommage : Le nom officiel de l'encodage source dont tous les caractères non alphanumériques sont remplacés par le caractère de soulignement, suivi de _to_, suivi du nom de l'encodage de destination transformé de la même manière. Par conséquent, ces noms diffèrent parfois des noms d'encodage montrés dans le Tableau 23.1.


23.3.5. 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.

https://www.unicode.org/

Le site web du Unicode Consortium.

RFC 3629

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