jueves, noviembre 20, 2008

El juego de caracteres de una base de datos



Hola, después del bonito fin de semana...vuelvo a la carga...

¿Quien no ha tenido problemas con el juego de caracteres de un móvil, de un sistema operativo, de una aplicación, de una base de datos,...?

Voy a hablar del caso concreto de Oracle, aunque lo importante es el concepto, y el concepto vale para cualquier base de datos.

En Oracle (y en el resto de base de datos) se establece un juego de caracteres para toda la base de datos.

Esta es una de las decisiones más importantes cuando creamos la base de datos ya que puede suponer importantes problemas o limitaciones en el futuro.

Como es obvio, dependiendo del juego elegido, unos caracteres se verán bien y otros no. Pero no sólo es eso.

Hay juegos de todo tipo, los hay estándares de sistemas operativos propietarios y no propietarios, estándares ISO y extendidos como los del fabricante Microsoft, para idiomas como el chino, el hebreo, el arabe o el japonés, etc. etc.

El problema es más complejo de lo que parece, porque podemos elegir un juego de caracteres muy completito, pero ¿qué ocurrirá cuando queramos exportar datos e importarlos en otra base de datos? O ¿si utilizamos productos de replicación (Oracle streams por ejemplo) como solución para contingencias? Pues lo primero que hay que comprobar es si hay compatibilidad entre los juegos de caracteres.

En un caso tipo de export-import, importarse se importarán los datos pero puede que no se importen bien las "ñ"-s, las "ë", los numeritos decimales y cosas por el estilo. Caracteres válidos en nuestro sistema pueden no serlo en otro y viceversa.

Además, al principio, la base de datos se contempla como algo aislado en la organización y es después cuando nos piden la interrelación con otra B.D.
El ejemplo típico es el de una fusión de empresas, un entorno de colaboración, o una internacionalización de nuestra organización, que de repente tiene que ser capaz de recoger información escrita en chino.

Mañana escribiré un post en detalle, pero de momento hoy empezaremos a aclarar unos conceptos básicos:

¿Qué es un juego de caracteres?

Un juego de caracteres es una correspondencia entre caracteres y valores binarios.

En juegos de caracteres de 8 bits podemos manejar 256 caracteres diferentes. Bueno, resumiendo es un sistema de codificación.
¿Por qué es importante?

Sólo podrás almacenar en la base de datos los caracteres admitidos por el juego de caracteres. También determinan los caracteres que se pueden utilizar en los procedimientos almacenados, etc.

¿Qué juego de caracteres tengo yo en mi base de datos?

En Oracle el juego de caracteres se almacena en el diccionario de datos. Se puede hacer la siguiente consulta para conocerlo:

SQL>select * from nls_database_parameters
where parameter='NLS_CHARACTERSET';
¿Qué juego de caracteres recomienda Oracle?

Yo aquí pongo lo que recomienda Oracle. No lo que recomiendo yo, que quede claro. Mañana lo explico mejor.

Oracle recomienda Unicode.

Si un juego de caracteres es un conjunto de caracteres, Unicode es el super-conjunto que agrupa a todos ellos.

Es un juego de caracteres universal. Incluye todos los caracteres de todos los idiomas.
En la actualidad hay más de 250 juegos de caracteres diferentes. Oracle considera que Unicode es el recomendado para la mayoría de clientes.

¿Qué problema se le puede ver al Unicode?

Para empezar no hay un Unicode. Hay varias versiones, y para una misma versión Oracle se han implementado diferentes versiones Unicode.

El tipo Unicode se incorpora a Oracle con la versión 7.2. Desde entonces Unicode ha ido modificándose continuamente.

Versiones 7.2 a 8.1 de Oracle: Juego de caracteres AL24UTFFSS que es Unicode version 1.1.

Versiones 8.0 a 10G: Juego de caracteres UTF8 que es Unicode 2.1 de 8.0 a 8.1.6 y Unicode 3.0 de 8.1.7 a 10G.

Versiones 9.0 a 10G: Juego de caracteres UTFE que es Unicode 2.1 de 8.0 a 8.1.6 y Unicode 3.0 de 8.1.7 a 10G.
Versiones 9.0 a 10G: Juego de caracteres AL32UTF8 que es Unicode 3.0 en 9.0 y unicode 3.1 de 9.2 a 10.1.

Versiones 9.0 a 10G: Juego de caracteres AL16UTF16
Menudo lío el Unicode ¿eh?

3 comentarios:

Anónimo dijo...

hola amigo, que tal..gracias por esa informacion ya que yo tengo un problema con lo que es la incompatibilidad de juego de caracteres....yo uso la version 9 de oracle y queria importar a otro pc, pero este equipo tiene la version 10..como puedo resolver ese problema para que me pueda restaurar la base de datos en ese equipo...por fa si puedes ayudarme te lo agradeceria, aqui te dejo mi correo: angeluz.arkanus.eptc@gmail.com

Aitor Iriarte dijo...

Hola,
Perdón por el retraso, pero es que ha sido un fin de semana movidito.

Necesito saber el juego de caracteres que tienes en Oracle 9 y en el Oracle 10.

Te envío un correo para que me contestes.

Saludos.

Anónimo dijo...

Hola buenas tardes yo quisiera saber como hacer compatibles los juegos de caracteres de una versión oracle 9i en solaris a oracle 12c ojalá puedas orientarme ya que tengo registros guardados con codificacion UTF8 y otros con carateres especiales que no quisiera que se batieran.

pretendo exportar e importar a menos que me recomiendes otra forma.

Mi correo es alejandro.ledesma68@gmail.com y estas son las caracteristicas de las bases de datos.

Agradeciendo de antemano la atención Alejandro Ledesma

BASE DE DATOS ORIGEN

PARAMETER VALUE
------------------------------ ----------------------------------------
NLS_CALENDAR GREGORIAN
NLS_CHARACTERSET WE8ISO8859P1
NLS_COMP BINARY
NLS_CURRENCY $
NLS_DATE_FORMAT DD-MON-RR
NLS_DATE_LANGUAGE AMERICAN
NLS_DUAL_CURRENCY $
NLS_ISO_CURRENCY AMERICA
NLS_LANGUAGE AMERICAN
NLS_LENGTH_SEMANTICS BYTE
NLS_NCHAR_CHARACTERSET AL16UTF16
NLS_NCHAR_CONV_EXCP FALSE
NLS_NUMERIC_CHARACTERS .,
NLS_RDBMS_VERSION 9.2.0.1.0
NLS_SORT BINARY
NLS_TERRITORY AMERICA
NLS_TIMESTAMP_FORMAT DD-MON-RR HH.MI.SSXFF AM
NLS_TIMESTAMP_TZ_FORMAT DD-MON-RR HH.MI.SSXFF AM TZR
NLS_TIME_FORMAT HH.MI.SSXFF AM
NLS_TIME_TZ_FORMAT HH.MI.SSXFF AM TZR

BASE DE DATOS DESTINO

PARAMETER VALUE
------------------------------ ----------------------------------------
NLS_CALENDAR GREGORIAN
NLS_CHARACTERSET WE8MSWIN1252
NLS_COMP BINARY
NLS_CURRENCY $
NLS_DATE_FORMAT DD-MON-RR
NLS_DATE_LANGUAGE AMERICAN
NLS_DUAL_CURRENCY $
NLS_ISO_CURRENCY AMERICA
NLS_LANGUAGE AMERICAN
NLS_LENGTH_SEMANTICS BYTE
NLS_NCHAR_CHARACTERSET AL16UTF16
NLS_NCHAR_CONV_EXCP FALSE
NLS_NUMERIC_CHARACTERS .,
NLS_RDBMS_VERSION 12.1.0.2.0
NLS_SORT BINARY
NLS_TERRITORY AMERICA
NLS_TIMESTAMP_FORMAT DD-MON-RR HH.MI.SSXFF AM
NLS_TIMESTAMP_TZ_FORMAT DD-MON-RR HH.MI.SSXFF AM TZR
NLS_TIME_FORMAT HH.MI.SSXFF AM
NLS_TIME_TZ_FORMAT HH.MI.SSXFF AM TZR