23.3. Soporte de juegos de caracteres #

23.3.1. Juegos de caracteres admitidos
23.3.2. Establecimiento del juego de caracteres
23.3.3. Conversión automática de juegos de caracteres entre servidor y cliente
23.3.4. Conversiones de juegos de caracteres disponibles
23.3.5. Lecturas adicionales

El soporte de juegos de caracteres en PostgreSQL te permite almacenar texto en una variedad de juegos de caracteres (también llamados codificaciones - encodings), incluidos juegos de caracteres de un solo byte como la serie ISO 8859 y juegos de caracteres de múltiples bytes como EUC (Extended Unix Code), UTF-8 y código interno de Mule. Todos los juegos de caracteres compatibles pueden ser utilizados de forma transparente por los clientes, pero unos pocos no son compatibles para su uso dentro del servidor (es decir, como codificación del lado del servidor). El juego de caracteres por defecto se selecciona al inicializar el clúster de bases de datos de PostgreSQL utilizando initdb. Se puede anular al crear una base de datos, por lo que puedes tener múltiples bases de datos, cada una con un juego de caracteres diferente.

Sin embargo, una restricción importante es que el juego de caracteres de cada base de datos debe ser compatible con los ajustes de configuración regional LC_CTYPE (clasificación de caracteres) y LC_COLLATE (orden de clasificación de cadenas) de la base de datos. Para la configuración regional C o POSIX, se permite cualquier juego de caracteres, pero para otras configuraciones regionales proporcionadas por libc hay solo un juego de caracteres que funcionará correctamente. (En Windows, sin embargo, la codificación UTF-8 se puede utilizar con cualquier configuración regional). Si tienes configurado el soporte de ICU, las configuraciones regionales proporcionadas por ICU se pueden utilizar con la mayoría de las codificaciones del lado del servidor, pero no con todas.

23.3.1. Juegos de caracteres admitidos #

La Table 23.3 muestra los juegos de caracteres disponibles para su uso en PostgreSQL.

Table 23.3. Juegos de caracteres de PostgreSQL

NombreDescripciónIdioma¿Servidor?¿ICU?Bytes/​Caráct.Aliases
BIG5Big FiveChino tradicionalNoNo1–2WIN950, Windows950
EUC_CNExtended UNIX Code-CNChino simplificado1–3 
EUC_JPExtended UNIX Code-JPJaponés1–3 
EUC_JIS_2004Extended UNIX Code-JP, JIS X 0213JaponésNo1–3 
EUC_KRExtended UNIX Code-KRCoreano1–3 
EUC_TWExtended UNIX Code-TWChino tradicional, taiwanés1–4 
GB18030Estándar nacionalChinoNoNo1–4 
GBKEstándar nacional extendidoChino simplificadoNoNo1–2WIN936, Windows936
ISO_8859_5ISO 8859-5, ECMA 113Latino/Cirílico1 
ISO_8859_6ISO 8859-6, ECMA 114Latino/Árabe1 
ISO_8859_7ISO 8859-7, ECMA 118Latino/Griego1 
ISO_8859_8ISO 8859-8, ECMA 121Latino/Hebreo1 
JOHABJOHABCoreano (Hangul)NoNo1–3 
KOI8RKOI8-RCirílico (Ruso)1KOI8
KOI8UKOI8-UCirílico (Ucraniano)1 
LATIN1ISO 8859-1, ECMA 94Europa occidental1ISO88591
LATIN2ISO 8859-2, ECMA 94Europa central1ISO88592
LATIN3ISO 8859-3, ECMA 94Europa del sur1ISO88593
LATIN4ISO 8859-4, ECMA 94Europa del norte1ISO88594
LATIN5ISO 8859-9, ECMA 128Turco1ISO88599
LATIN6ISO 8859-10, ECMA 144Nórdico1ISO885910
LATIN7ISO 8859-13Báltico1ISO885913
LATIN8ISO 8859-14Celta1ISO885914
LATIN9ISO 8859-15LATIN1 con Euro y acentos1ISO885915
LATIN10ISO 8859-16, ASRO SR 14111RumanoNo1ISO885916
MULE_INTERNALCódigo interno de MuleEmacs multilingüeNo1–4 
SJISShift JISJaponésNoNo1–2Mskanji, ShiftJIS, WIN932, Windows932
SHIFT_JIS_2004Shift JIS, JIS X 0213JaponésNoNo1–2 
SQL_ASCIIsin especificar (ver texto)cualquieraNo1 
UHCUnified Hangul CodeCoreanoNoNo1–2WIN949, Windows949
UTF8Unicode, 8 bitstodos1–4Unicode
WIN866Windows CP866Cirílico1ALT
WIN874Windows CP874TailandésNo1 
WIN1250Windows CP1250Europa central1 
WIN1251Windows CP1251Cirílico1WIN
WIN1252Windows CP1252Europa occidental1 
WIN1253Windows CP1253Griego1 
WIN1254Windows CP1254Turco1 
WIN1255Windows CP1255Hebreo1 
WIN1256Windows CP1256Árabe1 
WIN1257Windows CP1257Báltico1 
WIN1258Windows CP1258Vietnamita1ABC, TCVN, TCVN5712, VSCII

No todas las API cliente admiten todos los juegos de caracteres enumerados. Por ejemplo, el controlador JDBC de PostgreSQL no admite MULE_INTERNAL, LATIN6, LATIN8 y LATIN10.

El ajuste SQL_ASCII se comporta de manera considerablemente diferente a los otros ajustes. Cuando el juego de caracteres del servidor es SQL_ASCII, el servidor interpreta los valores de bytes 0–127 de acuerdo con el estándar ASCII, mientras que los valores de bytes 128–255 se toman como caracteres no interpretados. No se realizará ninguna conversión de codificación cuando el ajuste sea SQL_ASCII. Por lo tanto, este ajuste no es tanto una declaración de que se está utilizando una codificación específica, sino una declaración de ignorancia sobre la codificación. En la mayoría de los casos, si estás trabajando con datos que no son ASCII, no es prudente utilizar el ajuste SQL_ASCII porque PostgreSQL no podrá ayudarte convirtiendo o validando caracteres que no sean ASCII.

23.3.2. Establecimiento del juego de caracteres #

initdb define el juego de caracteres (codificación) por defecto para un clúster de PostgreSQL. Por ejemplo:

initdb -E EUC_JP

establece el juego de caracteres por defecto en EUC_JP (Código Unix extendido para japonés). Puedes utilizar --encoding en lugar de -E si prefieres cadenas de opciones más largas. Si no se proporciona ninguna opción -E o --encoding, initdb intenta determinar la codificación adecuada a utilizar en función de la configuración regional especificada o por defecto.

Puedes especificar una codificación que no sea la por defecto al momento de la creación de la base de datos, siempre que la codificación sea compatible con la configuración regional seleccionada:

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

Esto creará una base de datos llamada korean que utiliza el juego de caracteres EUC_KR y la configuración regional ko_KR. Otra forma de lograr esto es utilizar este comando SQL:

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

Ten en cuenta que los comandos anteriores especifican la copia de la base de datos template0. Al copiar cualquier otra base de datos, los ajustes de codificación y configuración regional no se pueden cambiar con respecto a los de la base de datos de origen, porque eso podría provocar la corrupción de los datos. Para más información, consulta la Section 22.3.

La codificación de una base de datos se almacena en el catálogo del sistema pg_database. Puedes verla utilizando la opción -l de psql o el comando \l.

$ 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

En la mayoría de los sistemas operativos modernos, PostgreSQL puede determinar qué juego de caracteres está implícito en el ajuste LC_CTYPE, y obligará a que solo se utilice la codificación de base de datos coincidente. En los sistemas más antiguos es tu responsabilidad asegurarte de utilizar la codificación esperada por la configuración regional que has seleccionado. Un error en esta área probablemente provocará un comportamiento extraño de las operaciones dependientes de la configuración regional, como la ordenación.

PostgreSQL permitirá a los superusuarios crear bases de datos con la codificación SQL_ASCII incluso cuando LC_CTYPE no sea C o POSIX. Como se señaló anteriormente, SQL_ASCII no obliga a que los datos almacenados en la base de datos tengan ninguna codificación en particular, por lo que esta elección plantea riesgos de mal comportamiento dependiente de la configuración regional. El uso de esta combinación de ajustes está obsoleto y podría prohibirse por completo algún día.

23.3.3. Conversión automática de juegos de caracteres entre servidor y cliente #

PostgreSQL admite la conversión automática de juegos de caracteres entre el servidor y el cliente para muchas combinaciones de juegos de caracteres (la Section 23.3.4 muestra cuáles).

Para habilitar la conversión automática de juegos de caracteres, debes indicarle a PostgreSQL el juego de caracteres (codificación) que deseas utilizar en el cliente. Existen varias formas de lograr esto:

  • Utilizar el comando \encoding en psql. \encoding te permite cambiar la codificación del cliente sobre la marcha. Por ejemplo, para cambiar la codificación a SJIS, escribe:

    \encoding SJIS
    

  • libpq (Section 32.11) tiene funciones para controlar la codificación del cliente.

  • Utilizar SET client_encoding TO. El establecimiento de la codificación del cliente se puede realizar con este comando SQL:

    SET CLIENT_ENCODING TO 'value';
    

    También puedes utilizar la sintaxis SQL estándar SET NAMES para este propósito:

    SET NAMES 'value';
    

    Para consultar la codificación actual del cliente:

    SHOW client_encoding;
    

    Para volver a la codificación por defecto:

    RESET client_encoding;
    

  • Utilizar PGCLIENTENCODING. Si la variable de entorno PGCLIENTENCODING está definida en el entorno del cliente, esa codificación del cliente se selecciona automáticamente cuando se realiza una conexión con el servidor. (Esto puede ser anulado posteriormente utilizando cualquiera de los otros métodos mencionados anteriormente).

  • Utilizar la variable de configuración client_encoding. Si la variable client_encoding está establecida, esa codificación del cliente se selecciona automáticamente cuando se realiza una conexión con el servidor. (Esto puede ser anulado posteriormente utilizando cualquiera de los otros métodos mencionados anteriormente).

Si la conversión de un carácter en particular no es posible — supongamos que elegiste EUC_JP para el servidor y LATIN1 para el cliente, y se devuelven algunos caracteres japoneses que no tienen representación en LATIN1 — se reporta un error.

Si el juego de caracteres del cliente se define como SQL_ASCII, se desactiva la conversión de codificación, independientemente del juego de caracteres del servidor. (Sin embargo, si el juego de caracteres del servidor no es SQL_ASCII, el servidor seguirá verificando que los datos entrantes sean válidos para esa codificación; por lo que el efecto neto es como si el juego de caracteres del cliente fuera el mismo que el del servidor). Al igual que para el servidor, el uso de SQL_ASCII no es sabio a menos que estés trabajando con datos que sean todos ASCII.

23.3.4. Conversiones de juegos de caracteres disponibles #

PostgreSQL permite la conversión entre dos juegos de caracteres cualesquiera para los cuales se liste una función de conversión en el catálogo del sistema pg_conversion. PostgreSQL viene con algunas conversiones predefinidas, como se resume en la Table 23.4 y se muestra con más detalle en la Table 23.5. Puedes crear una nueva conversión utilizando el comando SQL CREATE CONVERSION. (Para ser utilizada en conversiones automáticas cliente/servidor, una conversión debe estar marcada como default para su par de juegos de caracteres).

Table 23.4. Conversiones integradas de juegos de caracteres cliente/servidor

Juego de caracteres del servidorJuegos de caracteres del cliente disponibles
BIG5no admitido como codificación de servidor
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
GB18030no admitido como codificación de servidor
GBKno admitido como codificación de servidor
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
JOHABno admitido como codificación de servidor
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 a LATIN4, SJIS, WIN866, WIN1250, WIN1251
SJISno admitido como codificación de servidor
SHIFT_JIS_2004no admitido como codificación de servidor
SQL_ASCIIcualquiera (no se realizará ninguna conversión)
UHCno admitido como codificación de servidor
UTF8todas las codificaciones admitidas
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

Table 23.5. Todas las conversiones integradas de juegos de caracteres

Nombre de la conversión [a] Codificación de origenCodificación de destino
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] Los nombres de conversión siguen un esquema de nomenclatura estándar: El nombre oficial de la codificación de origen con todos los caracteres no alfanuméricos reemplazados por guiones bajos, seguido de _to_, seguido del nombre de la codificación de destino procesada de manera similar. Por lo tanto, estos nombres a veces se desvían de los nombres de codificación habituales que se muestran en la Table 23.3.


23.3.5. Lecturas adicionales #

Estas son buenas fuentes para comenzar a aprender sobre varios tipos de sistemas de codificación.

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

Contiene explicaciones detalladas de EUC_JP, EUC_CN, EUC_KR y EUC_TW.

https://www.unicode.org/

El sitio web del Consorcio Unicode.

RFC 3629

Aquí se define UTF-8 (formato de transformación de Unicode/UCS de 8 bits).