Fique ninja na codificação de caracteres …Ou muito do que você devia saber sobre encoding e tinha vergonha de perguntar.
Quem nunca ficou em dúvida sobre o funcionamento da codificação de caracteres? e como ela afeta a busca pela informação ou a forma de como ela é apresentada? Com frequencia essa questão vem a tona e poucos tem coragem de perguntar a respeito. Esta palestra tenta levar os curiosos ao mais alto nível de sabedoria, cobrindo questões de mapas de caractes, configurações no sistema operacional e necessariamente como que o PostgreSQL interage com tudo isso.
Esta palestra foi apresentada no PGBR 2015.
1. Fique ninja na
codificação de
caracteres
…Ou muito do que você devia
saber sobre encoding e tinha
vergonha de perguntar
Sebastian Webber
2. Sebastian Webber
Consultor na area de TI com expertise em PostgreSQL, JBoss e AWS
Instrutor de banco de dados
Já desistiu da faculdade umas 3 vezes…
Gosta muito de cozinhar
Ninja desde 2015
3. Afinal o que é encoding?
Uma codificação de caracteres é um padrão de relacionamento entre um
conjunto de caracteres com um conjunto de outra coisa, como por exemplo
números ou pulsos elétricos com o objetivo de facilitar o armazenamento de
texto em computadores...
…Ou uma forma de representar letras, números ou simbulos através de
numeros ou outros artificios.
5. No começo…
Letras e simbolos eram salvos em 7 BITS e isso permitia que todo o alfabeto e
simbolos comuns fossem representados através de códigos númericos… Estava
tudo certo pra quem falava inglês.
Aí o resto do mundo passou a comprar IBM PC fora da américa e pra cada
região, caracteres diferentes da lingua inglesa eram tratadas no 8º BIT
Code Pages foram criados para definir o escopo de cada lingua. Na pratica
todo e qualquer abaixo de 127 era igual, mas as diferenças eram tradadas
acima dele.
Linguas asiaticas precisaram mais de 1 byte para a representação de seus
ideogramas ou simbolos especificos
6.
7. Codificações ou Code Pages
A ISO padronizou code pages de
acordo com a região e lingua mas a
danada da Microsoft criou a sua
versão dos encodings para o ambiente
Windows.
Isso quer dizer que encondings como
LATIN1 (ISO 8859-1) e LATIN-9(ISO
8859-15) são equivalentes ao
WIN1251.
8. Universal Character Set
A fim de acabar com essa confusão e
multiplos padrões foi criado o Unicode
Ele é representado por 3 encodings:
UTF-8
UTF-16
UTF-32
9. Problemas comuns de encoding
Email, é claro!
Páginas da WEB que não utilizam UTF-8
A sua aplicação!
10. Como resolver?
Utilize UTF-8!
Se utf-8 ainda não tiver os
caracteres necessários pra
sua aplicação, avalie o UTF-
16 ou UTF-32
http://utf8everywhere.org
11. Por que devo migrar pra UTF-8?
Por que usar um encoding universal é muito mais fácil
Por que é um jeito fácil de não esquentar mais a cabeça com encoding
Por que você já usa e não sabe (seu SO deve estar usando).
E por que você não quer mais erros como esse na sua aplicação:
14. Aonde eu configuro o encoding?
Pra definir o default, é necessário fazer isso via initdb
Na criação da database. Seja no createdb:
..Ou no CREATE DATABASE:
initdb -E EUC_JP
createdb -E EUC_KR -T template0 korean_db
CREATE DATABASE korean_db WITH ENCODING
'EUC_KR' TEMPLATE=template0;
15. NÃO É POSSIVEL TROCAR
O ENCODING DEPOIS DE
CRIAR O BANCO!
16. Locale
O Suporte ao locale respeita as preferencias culturais como alfabetos,
ordenação, formatação numerica, etc.
O PostgreSQL usa o padrão ISO C e POSIX do sistema operacional
O suporte a locales é automaticamente na inicialização do cluster (criado
apartir do initdb)
17. Locale
As configurações de locale influenciam nos seguintes recursos SQL:
Ordem de ordenação de caracteres utilizando a clausula ORDER BY ou a
comparação de operações em campos do tipo texto (text, varchar, etc).
Nas funções UPPER, LOWER e INITCAP
Operadores de comparação de padrões (LIKE, SIMILAR TO e expressões regulares
POSIX)
As funções to_char
A possibilidade de utilizar indexes com o operador LIKE
18. Locale
Ocasionalmente é util combinar varios locales, por exemplo, utilizar regras de
collate em inglês (en_US) e exibir mensagens em espanhol (es_AR).
Para permitir esse tipo de combinação de vários locales, as variaveis abaixo
permitem a configuração específica:
LC_COLLATE Ordenação de caracteres
LC_CTYPE
Classificação de caracteres (o que é uma letra? É
equivalente a uma letra maiuscula?)
LC_MESSAGES Linguagem para exibir as mesas do servidor
LC_MONETARY Exibição de moedas
LC_NUMERIC Exibição de números
LC_TIME Exibição de datas e horários
19. Collation
Permite especificar o locale de ordenação (LC_COLLATE) e classificações de
caracteres (LC_CTYPE) a nível de colunas ou por operação.
Isso facilita a sua vida por permite que você utilizar um locale diferente do
criado no banco de dados.
CREATE TABLE test1 (
a text COLLATE "de_DE",
b text COLLATE "es_ES",
...
);
SELECT a < (’foo’ COLLATE
‘fr_FR’) FROM test1;
SELECT * FROM test1 ORDER BY
a || b COLLATE "fr_FR";
20. Como eu TROCO de um encoding pra
outro?
pg_dump e pg_restore
Replicação lógica (casando o encoding de origem com de destino)
https://en.wikipedia.org/wiki/UTF-16
The encoding is variable-length and uses 8-bit code units. It was designed for backward compatibility with ASCII, and to avoid the complications of endianness and byte order marks in the alternative UTF-16 and UTF-32 encodings. The name is derived from: Universal Coded Character Set + Transformation Format—8-bit.[1]
UTF-16 (16-bit Unicode Transformation Format) is a character encoding capable of encoding all 1,112,064 possible characters in Unicode. The encoding is variable-length, as code points are encoded with one or two 16-bit code units. (also see Comparison of Unicode encodings for a comparison of UTF-8, -16 & -32)
UTF-32 (or UCS-4) stands for Unicode Transformation Format 32 bits. It is a protocol to encode Unicode code points that uses exactly 32 bits per Unicode code point. This makes UTF-32 a fixed-length encoding, in contrast to all other Unicode transformation formats which are variable-length encodings. The UTF-32 form of a code point is a direct representation of that code point's numerical value.[1]