Wednesday, December 3, 2008

Character set

No momento da criação de um banco de dados oracle, definimos qual charset será utilizado no db, isto quer dizer, qual a quantidade de bytes necessários para um caracter, deve ser uma decisão muito bem estudada pois depois que definida não será possivel altera-la.

Assim, para o idioma ingles usamos bytes com 7 bits, sendo que na lingua inglesa não temos acentuação,apenas 7 bits seriam necessário para armazenar todos os caracteres possiveis, já para o portugues, onde o acento é rigidamente necessário, temos bytes formados por 8 bits, já para liguas como o chines e o japones onde temos de 2 a 4 mil caracteres distintos, devemos ter caracteres formados por diversos bytes, entre 2 a 4 dependendo da configuração escolhida.

Unicode e o single byte.

Unicode são caracteres codificados de uma maneira singular, indepente do idioma, codificado em um unico character set.
Usando unicode como caracter set, podemos então com apenas um caracter set armazenar diversos idiomas, como o Chines, japones, portugues, usando apenas um character set. É um grande facilitador, mas não havendo a necessidade, pode ser usado o single byte, é recomendável sempre optar pelo menor consumo.
Temos diversos tipos de charset para unicode, são eles, UTF-16, UTF-8 e UCS-2.
Uma das maneiras de se verificar o character é pela seguinte consulta:
select value from nls_database_parameters
where parameter = 'NLS_CHARACTERSET';


Um dos problemas ao migrar uma base de dados é alterar o número de bytes para cada caracter, sendo que o tipo de dados varchar depende do character set do banco, uma base anterior com single byte, ao ser migrada para uma base em unicode deve se pensar na possibilidade de aumentar o valor das variaveis em varchar, pois um caracter antes armazenado em um byte teria que ser amazenado em dois ou até mais. Nunca havi pensado nisso, pois nunca passei por esse tipo de problema, mas essa semana ao conversar com um amigo meu, ele relatou esse fato, ao migrar uma base haviam dados faltando em algumas colunas do tipo varchar, pois o vchar armazena tamanho fixo para bytes, portanto ao aumentar o número de bytes por caracter teriamos também que levar em consideração o número máximo de bytes para tais colunas.

Outro fato interessante é o tipo de dados nchar, o qual não limita o armazenamento de dados a bytes, e sim a número de caracteres, por tanto, ele sempre tera 200 caracteres limites, pois ele é tipo de dados unicode, independente do charset do banco ele irá armazenar em unicode. Esse tipo de dados nchar depende também do parametro national character.

Fontes:
http://www.adp-gmbh.ch/ora/database.html
http://download-uk.oracle.com/docs/cd/B19306_01/server.102/b14225/ch6unicode.htm#i1006826
http://download.oracle.com/docs/cd/B28359_01/server.111/b28318/datatype.htm#i14946
http://stanford.edu/dept/itss/docs/oracle/10g/server.101/b10749/ch7progrunicode.htm
http://www.dba-oracle.com/t_nls_lang.htm

2 comments:

Anonymous said...

Boa Tarde, estou tendo o seguinte problema.
Tenho 2 bancos de dados um Unicode e o outro não.
Exportei um usuário do banco unicode e importei no banco que não é unicode.
Enfim esse usuário que foi importando não está aceitando nenhum registro que tenha acentuação, como faço para resolver?

Diogo Nomura said...

Ola desculpe pela demora para responder, voce ja conseguiu resolver seu problema? Se não recomendo a dar uma olhada em duas feramentas, Database Character Set Scanner, csscan, e BMS_REDEFINITION.START_REDEF_TABLE para tentar alterar o character set inputado na sua base.
Caso já tenha resolvido poderia compartilhar?