{"id":1132,"date":"2022-03-11T13:50:35","date_gmt":"2022-03-11T16:50:35","guid":{"rendered":"https:\/\/gladiston.net.br\/?page_id=1132"},"modified":"2022-09-14T17:46:17","modified_gmt":"2022-09-14T20:46:17","slug":"qual-charset-devo-usar-iso8859_1-win1252-ou-utf8","status":"publish","type":"page","link":"https:\/\/gladiston.net.br\/en\/banco-de-dados\/qual-charset-devo-usar-iso8859_1-win1252-ou-utf8\/","title":{"rendered":"Which charset should I use? ISO8859_1 WIN1252 or UTF8?"},"content":{"rendered":"\n<p class=\"has-drop-cap\">Este artigo ainda est\u00e1 em rascunho, as informa\u00e7\u00f5es est\u00e3o corretas, mas falta ajustes na formata\u00e7\u00e3o, concord\u00e2ncia gramatical e achar uma maneira mais did\u00e1tica. Mas se entender, pode utiliz\u00e1-lo.<\/p>\n\n\n\n<p>Se voc\u00ea usa o Windows, voc\u00ea deve estar se perguntando porque essa pergunta \u00e9 importante.<br>Por gentileza abra o cmd e execute comigo o comando \u2018chcp\u2019, ele retorna o c\u00f3digo de p\u00e1gina de caracteres que est\u00e1 em uso no momento. Ele retornar\u00e1 o c\u00f3digo de p\u00e1gina \u2018850\u2019.<\/p>\n\n\n\n<p>Vamos no google e pesquisar esta p\u00e1gina com os termos \u2018Code page 850\u2019 e seremos encaminhamos para wikipedia:<\/p>\n\n\n\n<p><a href=\"https:\/\/en.wikipedia.org\/wiki\/Code_page_850\">https:\/\/en.wikipedia.org\/wiki\/Code_page_850<\/a><\/p>\n\n\n\n<p>E ent\u00e3o descobrimos que estamos usando o iso8859_1 tamb\u00e9m conhecido como \u2018Latin1\u2019. Ent\u00e3o, toda vez que nos referimos ao ISO8859_1, vamos chamar de Latin1, ok?<\/p>\n\n\n\n<p>Se voc\u00ea chegou a conhecer o MS-DOS deve se lembrar do comando chcp que usavamos no autoexec.bat para tornar poss\u00edvel ver as acentua\u00e7\u00f5es na tela. Ent\u00e3o desde os prim\u00f3rdios do MS-DOS usamos Latin1 (ou iso8859_1) para tornar poss\u00edvel ver nossas acentua\u00e7\u00f5es no terminal. Latin1 (ou iso8859_1) leva o prefixo \u2018iso\u2019 porque foi aprovado pelo comit\u00ea internacional de mesmo nome: International Organization for Standardization (Organiza\u00e7\u00e3o Internacional de Normaliza\u00e7\u00e3o) o equivalente a nossa ABNT s\u00f3 que internacional.<\/p>\n\n\n\n<p>Mas uma coisa \u00e9 o terminal, algo considerado legado por alguns para rodar aplica\u00e7\u00f5es. Quando o Windows surgiu com uma interface gr\u00e1fica, a microsoft resolveu criar um novo c\u00f3digo de p\u00e1gina chamado \u2018Win1252\u2019 por isso tem o \u2018Win\u2019 no nome, foi feito exclusivamente para o ambiente Windows e teve a aprova\u00e7\u00e3o da ANSI, a ABNT americana.<\/p>\n\n\n\n<p>Por que criar seu pr\u00f3prio padr\u00e3o ao inv\u00e9s de continuar usando o ISO8859_1(Latin1)? Essa \u00e9 uma pergunta dif\u00edcil de responder, o iso8859_1 foi criado inicialmente pela Apple e depois aprovado pela ISO e naquela \u00e9poca a Microsoft gostava de ditar os padr\u00f5es da ind\u00fastria e talvez por isso tenham criado o Win1252. Ele deveria ser desnecess\u00e1rio j\u00e1 que teve como base o pr\u00f3prio ISO8859_1 e ambos com poucas exce\u00e7\u00f5es s\u00e3o cambi\u00e1veis entre si. Pessoalmente, s\u00f3 conhe\u00e7o duas diferen\u00e7as entre ambos, o Win1252 possui um travess\u00e3o longo que \u00e9 diferente do tra\u00e7o normal e um jogo de aspas com serifa(curva)<\/p>\n\n\n\n<p>Ter um padr\u00e3o de gera\u00e7\u00e3o de caracteres diferentes s\u00f3 criou problemas para a Microsoft, seu terminal(cmd) \u00e9 Latin1, a interface gr\u00e1fica \u00e9 Win1252, o sistema de arquivos \u00e9 UNICODE. A pouco tempo atr\u00e1s, se voc\u00ea usasse um bloco de notas para editar um arquivo php ou html tinha boas chances de ter o seu trabalho perdido. Sistemas como o Linux s\u00e3o tudo UNICODE e normalmente n\u00e3o \u00e9 preciso lidar com convers\u00f5es entre c\u00f3digo de p\u00e1ginas diferentes.<\/p>\n\n\n\n<p>Um outro problema como o ambiente Windows \u00e9 que ele n\u00e3o \u00e9 mais t\u00e3o universal como antes, hoje as aplica\u00e7\u00f5es est\u00e3o em nuvem e a maioria dos servi\u00e7os de banco de dados s\u00e3o hospedados em computadores que n\u00e3o rodam Windows. Se voc\u00ea hospedar dados num servidor Windows armazenando dados no formato WIN1252 provavelmente teria de pensar o que aconteceria se resolvesse hospedar um banco de dados num sistema operacional Linux que segue apenas padr\u00f5es internacionais ISO onde o WIN1252 n\u00e3o existe. Voc\u00ea talvez tenha de lidar com problemas de translitera\u00e7\u00e3o de caracteres.<\/p>\n\n\n\n<p>[todo: mostrar no notepad++ essa translitera\u00e7\u00e3o]<\/p>\n\n\n\n<p>Ent\u00e3o, o desej\u00e1vel se queremos uma aplica\u00e7\u00e3o ou banco de dados que seja port\u00e1vel entre sistemas operacionais \u00e9 desistir do WIN1252 e em seu lugar optar pelo ISO8859_1(latin1). Agora, daqui em diante vou falar apenas do Latin1(ISO8859_1) e o padr\u00e3o Unicode. Mas ao me referir ao Latin1, lembre-se que tamb\u00e9m \u00e9 aplic\u00e1vel ao WIN1252.<\/p>\n\n\n\n<p>O UNICODE veio para resolver alguns problemas, H\u00e1 uma \u00f3tima palestra Firebird Conference 2011 Luxembourg onde o discursante falou muito sobre charsets, na sua palestra intitulada \u201cCharacter Sets and Unicode in Firebird\u201d e citou as vantagens:<\/p>\n\n\n<p>[vou incluir no video o link:<br \/>\nhttps:\/\/www.firebirdsql.org\/file\/community\/ppts\/fbcon11\/FbCon2011-Charsets-Heymann.pdf<br \/>\n]<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Um \u00fanico conjunto de caracteres para todos os idiomas \/ scripts<\/li><li>Sem sobreposi\u00e7\u00f5es de c\u00f3digo, n\u00e3o \u00e9 necess\u00e1rio um c\u00f3digo arbitr\u00e1rio para corrigir incongru\u00eancias<\/li><li>Independente de hardware e sistema operacional<\/li><\/ul>\n\n\n\n<p>todo: mostrar o exemplo no terminal do linux, mudando o prompt para exibir caracteres latinos e utf<\/p>\n\n\n\n<p>todo: no windows trocar code page de 850 para chcp 65001<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>chcp<\/code><\/pre>\n\n\n\n<p>Comprovamos ent\u00e3o que estamos usando o latin1, vamos agora mudar para win1252:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>chcp 1252<br>echo linha #1: teste com com p\u00e1gina latin1(iso8859_1)&gt;teste.txt<br>echo linha #2: aten\u00e7\u00e3o, minha acentua\u00e7\u00e3o \u00e9 inoq\u00fca&gt;&gt;teste.txt<br>hexeditor teste.txt<\/code><\/pre>\n\n\n\n<p>Parece tudo certo, n\u00e9? mas vamos mudar agora o c\u00f3digo da p\u00e1gina para utf:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>chcp 65001<br>echo linha #3: teste com com p\u00e1gina unicode&gt;&gt;teste.txt<br>echo linha #4: aten\u00e7\u00e3o, minha acentua\u00e7\u00e3o \u00e9 inoq\u00fca&gt;&gt;teste.txt<br>hexeditor teste.txt<\/code><\/pre>\n\n\n\n<p>Aagora temos duas linhas iniciais exibidas corretamente, mas as duas ultimas erroneamente, por que? Porque ao iniciar o arquivo pela primeira vez, n\u00e3o h\u00e1 indicativos de codepage dentro do arquivo e ent\u00e3o o windows assume que \u00e9 Ansi.<\/p>\n\n\n\n<p>Vamos criar as mesmas 4 linhas no notepad++, note que o mesmo j\u00e1 \u00e9 criado em UTF8<br>mas se olharmos no bloco de notas, notaremos que nenhuma das linhas parece correta porque nem Latin1 e nem UTF s\u00e3o compat\u00edveis com o WIN1252(Ansi).<\/p>\n\n\n\n<p>Se usarmos o notepad++ e convertermos o arquivo para UTF-8 (Formatar-&gt;Codifica\u00e7\u00e3o UTF-8 ou europa ocidental) as duas primeiras ou as duas \u00faltimas linhas est\u00e3o corretas, mas nunca as 4 linhas.<\/p>\n\n\n\n<p>Mas se o unicode \u00e9 t\u00e3o bom, porque n\u00e3o usamos?<\/p>\n\n\n\n<p>Usamos o tempo todo, a Microsoft j\u00e1 se rendeu ao UNICODE no desenvolvimento, embora o Windows ainda tenha uma salada de c\u00f3digo de p\u00e1ginas, por exemplo, o sistema de arquivos \u00e9 unicode, o ambiente gr\u00e1fico ainda \u00e9 win1252 e o cmd(terminal) Lantin1, por isso, h\u00e1 muitas inconsist\u00eancias quando programamos em Windows visando o unicode. Se um programador gerar um script SQL e salv\u00e1-lo no disco usando WIN1252, mas os caracteres gerados nele estiverem em UNICODE, haver\u00e1 problemas. Se voc\u00ea teve de criar editar um arquivo unicode usando bloco de notas e depois percebeu.<\/p>\n\n\n\n<p>todo: demonstrar um script SQL usando o IBExpert, banco de dados UTF-8 n\u00e3o vai rodar um script aparentemente inofensivo que foi feito em Win1252.<\/p>\n\n\n\n<p>Isso \u00e9 um inferno que apenas existe no Windows, e que quando voc\u00ea tentar portar para Linux tem de resolver problemas que antes n\u00e3o existiam. Por isso, para nossa comodidade, os bancos de dados incluam WIN1252 entre os seus charsets, embora o mesmo n\u00e3o seja o ideal.<\/p>\n\n\n\n<p>Ainda sobre banco de dados, nem sempre o UNICODE \u00e9 desej\u00e1vel, pois um \u00fanico caractere armazenado nele pode ocupar de 1 a 4 bytes, por isso, n\u00e3o \u00e9 largamente utilizado se uma aplica\u00e7\u00e3o j\u00e1 \u201cfala\u201d ISO8859_1 ou WIN1252, pois na\u00e7\u00f5es que usam ideogramas ou outros s\u00edmbolos tipogr\u00e1ficos tamb\u00e9m sabem \u201cfalar\u201d ISO8859_1 ou WIN1252, embora o inverso n\u00e3o seja verdadeiro, se voc\u00ea fosse de uma empresa japonesa teria de escrever uma aplica\u00e7\u00f5es que usasse os ideogramas japoneses e muito provavelmente tamb\u00e9m o ocidental e s\u00f3 o UNICODE resolveria este problema.<\/p>\n\n\n\n<p>Ent\u00e3o se voc\u00ea mora num pa\u00eds ocidental que usa os caracteres A-Z pode-se considerar sortudo porque temos op\u00e7\u00f5es de escolha, e geralmente optamos pela mais econ\u00f4mica que tamb\u00e9m \u00e9 a mais perform\u00e1tica, desconsiderar UNICODE e escolher entre WIN1252 ou ISO8859_1.<br>Um banco de dados inteiramente em UNICODE \u00e9 menos perform\u00e1tico quando comparado ao Latin1, n\u00e3o apenas por ser mais guloso em termos de espa\u00e7o, lembre-se um varchar(64) a depender do UNICODE usado, ao inves de 64 caracteres pode conter apenas 16, mas tamb\u00e9m porque o algoritmo de \u2018case insensitive\u2019 e \u2018accent insensitive&#8217; podem vir a ser mais complexos. O MySQL por exemplo, \u00e9 reconhecido por adotar uma gambiarra de UNICODE que \u00e0s vezes criam problemas.<\/p>\n\n\n\n<p>IBExpert &#8211; Criar banco de dados :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>C:\\TEMP\\TEST_ISO8859_1.FDB<br>CHARSET: ISO8859_1<br>COLLATE: PT_BR<br>ALIAS: TEST_ISO8859_1.FDB<br>PORTA: 3040<\/code><\/pre>\n\n\n\n<p>&#8212; CRIAR A TABELA:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:false,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;sql&quot;,&quot;mime&quot;:&quot;text\/x-sql&quot;,&quot;theme&quot;:&quot;default&quot;,&quot;lineNumbers&quot;:true,&quot;styleActiveLine&quot;:true,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;TrpContentRestriction&quot;:{&quot;restriction_type&quot;:&quot;exclude&quot;,&quot;selected_languages&quot;:[],&quot;panel_open&quot;:true},&quot;language&quot;:&quot;SQL&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;sql&quot;}\">CREATE TABLE T1(\n    FRUTA_ISO8859 VARCHAR(10) CHARACTER SET ISO8859_1 COLLATE PT_BR,\n    FRUTA_WIN1252 VARCHAR(10) CHARACTER SET WIN1252 COLLATE WIN_PTBR,\n    FRUTA_UNICODE VARCHAR(10) CHARACTER SET UTF8 COLLATE UNICODE_CI_AI\n);\n<\/pre><\/div>\n\n\n\n<p>POPULAR VALORES ACENTUADOS COM O SCRIPT:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:false,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;sql&quot;,&quot;mime&quot;:&quot;text\/x-sql&quot;,&quot;theme&quot;:&quot;default&quot;,&quot;lineNumbers&quot;:true,&quot;styleActiveLine&quot;:true,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;TrpContentRestriction&quot;:{&quot;restriction_type&quot;:&quot;exclude&quot;,&quot;selected_languages&quot;:[],&quot;panel_open&quot;:true},&quot;language&quot;:&quot;SQL&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;sql&quot;}\">INSERT INTO T1 (FRUTA_ISO8859, FRUTA_WIN1252, FRUTA_UNICODE)\n            VALUES ('Maracuj\u00e1', 'Maracuj\u00e1', 'Maracuj\u00e1');\nINSERT INTO T1 (FRUTA_ISO8859, FRUTA_WIN1252, FRUTA_UNICODE)\n            VALUES ('A\u00e7a\u00ed', 'A\u00e7a\u00ed', 'A\u00e7a\u00ed');\nINSERT INTO T1 (FRUTA_ISO8859, FRUTA_WIN1252, FRUTA_UNICODE)\n            VALUES ('Gravat\u00e1', 'Gravat\u00e1', 'Gravat\u00e1');\nINSERT INTO T1 (FRUTA_ISO8859, FRUTA_WIN1252, FRUTA_UNICODE)\n            VALUES ('Avel\u00e3', 'Avel\u00e3', 'Avel\u00e3');\nINSERT INTO T1 (FRUTA_ISO8859, FRUTA_WIN1252, FRUTA_UNICODE)\n            VALUES ('Mel\u00e3o', 'Mel\u00e3o', 'Mel\u00e3o');\nINSERT INTO T1 (FRUTA_ISO8859, FRUTA_WIN1252, FRUTA_UNICODE)\n            VALUES ('Ma\u00e7\u00e3', 'Ma\u00e7\u00e3', 'Ma\u00e7\u00e3');\nINSERT INTO T1 (FRUTA_ISO8859, FRUTA_WIN1252, FRUTA_UNICODE)\n            VALUES ('Mam\u00e3o', 'Mam\u00e3o', 'Mam\u00e3o');\nINSERT INTO T1 (FRUTA_ISO8859, FRUTA_WIN1252, FRUTA_UNICODE)\n            VALUES ('Jil\u00f3', 'Jil\u00f3', 'Jil\u00f3');\nINSERT INTO T1 (FRUTA_ISO8859, FRUTA_WIN1252, FRUTA_UNICODE)\n            VALUES ('Baba\u00e7u', 'Baba\u00e7u', 'Baba\u00e7u');\n\nCOMMIT WORK;\n<\/pre><\/div>\n\n\n\n<p>Ser\u00e1 que todos os caracteres tem o mesmo tamanho em bytes? Execute:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:false,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;sql&quot;,&quot;mime&quot;:&quot;text\/x-sql&quot;,&quot;theme&quot;:&quot;default&quot;,&quot;lineNumbers&quot;:true,&quot;styleActiveLine&quot;:true,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;TrpContentRestriction&quot;:{&quot;restriction_type&quot;:&quot;exclude&quot;,&quot;selected_languages&quot;:[],&quot;panel_open&quot;:true},&quot;language&quot;:&quot;SQL&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;sql&quot;}\">select\n  a.fruta_iso8859||'('||octet_length(a.fruta_iso8859)||')' as iso8859,\n  a.fruta_win1252||'('||octet_length(a.fruta_win1252)||')' as win1252,\n  a.fruta_unicode||'('||octet_length(a.fruta_unicode)||')' as unicode\nfrom T1 a\n<\/pre><\/div>\n\n\n\n<p>Entre as nossas frutas o limite de caracteres \u00e9 10, o maracuj\u00e1 foi a fruta mais ocupou espa\u00e7o em bytes com 9 bytes em unicode. O que vai acontecer se aumentar para 10 caracteres e acentuarmos ainda mais letras? Vamos conferir:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:false,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;sql&quot;,&quot;mime&quot;:&quot;text\/x-sql&quot;,&quot;theme&quot;:&quot;default&quot;,&quot;lineNumbers&quot;:true,&quot;styleActiveLine&quot;:true,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;TrpContentRestriction&quot;:{&quot;restriction_type&quot;:&quot;exclude&quot;,&quot;selected_languages&quot;:[],&quot;panel_open&quot;:true},&quot;language&quot;:&quot;SQL&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;sql&quot;}\">update T1 set\n  FRUTA_UNICODE='Mar\u00e1\u00e7uj\u00e3\u00edo' -- 10 caracteres, deveria caber, o limite \u00e9 10\nwhere FRUTA_UNICODE='Maracuj\u00e1';\n<\/pre><\/div>\n\n\n\n<p>Conseguimos, mas note a diverg\u00eancia entre o tamanho de caracteres e o tamanho de byte ocupados:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:false,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;sql&quot;,&quot;mime&quot;:&quot;text\/x-sql&quot;,&quot;theme&quot;:&quot;default&quot;,&quot;lineNumbers&quot;:true,&quot;styleActiveLine&quot;:true,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;TrpContentRestriction&quot;:{&quot;restriction_type&quot;:&quot;exclude&quot;,&quot;selected_languages&quot;:[],&quot;panel_open&quot;:true},&quot;language&quot;:&quot;SQL&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;sql&quot;}\">select\n  a.fruta_iso8859||octet_length(a.fruta_iso8859),\n  a.fruta_win1252||octet_length(a.fruta_win1252),\n  a.fruta_unicode||octet_length(a.fruta_unicode)\nfrom T1 a\nwhere FRUTA_UNICODE='Mar\u00e1\u00e7uj\u00e3\u00edo' \n<\/pre><\/div>\n\n\n\n<p>Maracuj\u00e1 tem 10 caracteres, mas ocupa agora 14 bytes. Ent\u00e3o o tamanho de um campo n\u00e3o \u00e9 o mesmo que dizer que o tamanho ocupado. O que acha que aconteceria se todas as 10 letras tivesse acento? Vamos tentar:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:false,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;sql&quot;,&quot;mime&quot;:&quot;text\/x-sql&quot;,&quot;theme&quot;:&quot;default&quot;,&quot;lineNumbers&quot;:true,&quot;styleActiveLine&quot;:true,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;TrpContentRestriction&quot;:{&quot;restriction_type&quot;:&quot;exclude&quot;,&quot;selected_languages&quot;:[],&quot;panel_open&quot;:true},&quot;language&quot;:&quot;SQL&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;sql&quot;}\">update T1 set\nFRUTA_UNICODE='\u00e1\u00e9\u00ed\u00f3\u00fa\u00e1\u00e9\u00ed\u00f3\u00fa'-- 10 caracteres\nwhere FRUTA_UNICODE='Mar\u00e1\u00e7uj\u00e3\u00edo'<\/pre><\/div>\n\n\n\n<p>Chegamos ent\u00e3o a conclus\u00e3o que em unicode &#8211; em especial UTF-8 &#8211; o armazenamento do seu banco ser\u00e3 maior contendo acentua\u00e7\u00f5es do que seria em Latin1 ou Ansi.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Com o armazenamento t\u00e3o barato, devo me preocupar?<\/h2>\n\n\n\n<p>Se seu objetivo for internacionalizar, n\u00e3o deve se preocupar com o armazenamento, mas deve se preocupar com os limites te\u00f3ricos de seus metadados,  como nome de objetos. Por exemplo, se eu criar uma tabela cuja chave \u00e9 um varchar(x) qual \u00e9 o tamanho m\u00e1ximo de uma chave dentro de um \u00edndice? No FirebirdSQL, este tamanho \u00e9 \u00bc do tamanho da pagina de dados. Se por exemplo, seu banco tem paginas de 4kb, significa que o tamanho de um \u00edndice n\u00e3o vai poder ultrapassar 1k ent\u00e3o um indice simples ou composto que tenha mais de 1024bytes n\u00e3o ser\u00e1 poss\u00edvel. Ent\u00e3o quando estiver usando unicode tome cuidado com os limites do FirebirdSQL que forem em bytes, pois o que antes era 1 byte=1 caractere n\u00e3o \u00e9 mais aplic\u00e1vel. Os limites que eram estabelecidos em caracteres, estes n\u00e3o mudam, se o limite para tamanho de nome para uma tabela \u00e9 63 caracteres, continuar\u00e1 sendo 63 caracteres n\u00e3o importando se \u00e9 unicode ou n\u00e3o. <\/p>\n\n\n\n<p>Aqui temos uma gritante diferen\u00e7a para iso8859_1 ou win1252, pois nestes cada caractere \u00e9 1 byte, enquanto em unicode o FirebirdSQL assume que cada caractere consumido \u00e9 4 bytes. Ent\u00e3o se voce criar um campo varchar(18000) e inserir 18.000 caracteres acentuados, ele ir\u00e1 deixar, mas o espa\u00e7o ocupado ser\u00e1 18.000&#215;2 ou 18.000&#215;4 dependendo do acento.<\/p>\n\n\n\n<p>Portanto, quando criar um campo que voc\u00ea sabe que no m\u00e1ximo ter\u00e1 X caracteres, leve em considera\u00e7\u00e3o:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>O tamanho declarado n\u00e3o \u00e9 o mesmo de tamanho ocupado.<\/li><li>Cuidado com o metadados, se um tipo de limite for informado em bytes ent\u00e3o usando unicode voc\u00ea ter\u00e1 4x menos do que o informado.<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">VAMOS AO COLLATE<\/h2>\n\n\n\n<p>Charset \u00e9 o conjunto de caracteres dispon\u00edveis, majoritariamente ISO8859_1, WIN1252 e UNICODE. Cada qual com o seu conjunto limitados de caracteres. Se seu banco de dados precisa de caracteres latinos e ocidental ISO8859_1 t\u00e1 bom para voc\u00ea, voc\u00ea n\u00e3o deveria usar o WIN1252 porque ele foi provido apenas para Windows e sua condi\u00e7\u00e3o pode mudar no futuro.<\/p>\n\n\n\n<p>Mas se precisa dum conjunto grande de caracteres que permita escrever na mesma senten\u00e7a caracteres ocidentais e ideogramas japoneses ent\u00e3o voc\u00ea tem que optar pelo UNICODE, geralmente UTF-8. <\/p>\n\n\n\n<p>O collate \u00e9 a forma como os caracteres ser\u00e3o tratados e\/ou ordenados. Ser\u00e1 que &#8216;A&#8217; vem antes &#8216;\u00e1&#8217;? Ser\u00e1 que &#8216;Pharmacia&#8217; e Farmacia&#8217; \u00e9 a mesma coisa? Ser\u00e1 que &#8216;Jos\u00e9&#8217; e &#8216;Jose&#8217; tamb\u00e9m s\u00e3o iguais?<\/p>\n\n\n\n<p>Quem cria os collates define isso, no Brasil n\u00e3o tem essa coisa de &#8216;Ph&#8217; de pharmacia dos anos 30, mas em outros pa\u00edses podem haver agrupamento de caracteres(collate) que devam ser tratados conjuntamente e n\u00e3o de forma individual.<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:false,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;sql&quot;,&quot;mime&quot;:&quot;text\/x-sql&quot;,&quot;theme&quot;:&quot;default&quot;,&quot;lineNumbers&quot;:true,&quot;styleActiveLine&quot;:true,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;TrpContentRestriction&quot;:{&quot;restriction_type&quot;:&quot;exclude&quot;,&quot;selected_languages&quot;:[],&quot;panel_open&quot;:true},&quot;language&quot;:&quot;SQL&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;sql&quot;}\">CREATE TABLE T2 (\n    NOME  VARCHAR(30) NOT NULL COLLATE PT_BR\n);\n<\/pre><\/div>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:false,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;sql&quot;,&quot;mime&quot;:&quot;text\/x-sql&quot;,&quot;theme&quot;:&quot;default&quot;,&quot;lineNumbers&quot;:true,&quot;styleActiveLine&quot;:true,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;TrpContentRestriction&quot;:{&quot;restriction_type&quot;:&quot;exclude&quot;,&quot;selected_languages&quot;:[],&quot;panel_open&quot;:true},&quot;language&quot;:&quot;SQL&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;sql&quot;}\">INSERT INTO T2 (NOME)   VALUES ('FARMACIA');\nINSERT INTO T2 (NOME)   VALUES ('FARM\u00c1CIA');\nINSERT INTO T2 (NOME)   VALUES ('Jose');\nINSERT INTO T2 (NOME)    VALUES ('Jos\u00e9');\nINSERT INTO T2 (NOME)    VALUES ('JOS\u00c9');\n<\/pre><\/div>\n\n\n\n<p>Note agora a ordena\u00e7\u00e3o de dados entre dois colates diferentes usando o mesmo charset:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:false,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;sql&quot;,&quot;mime&quot;:&quot;text\/x-sql&quot;,&quot;theme&quot;:&quot;default&quot;,&quot;lineNumbers&quot;:true,&quot;styleActiveLine&quot;:true,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;TrpContentRestriction&quot;:{&quot;restriction_type&quot;:&quot;exclude&quot;,&quot;selected_languages&quot;:[],&quot;panel_open&quot;:true},&quot;language&quot;:&quot;SQL&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;sql&quot;}\">SELECT * FROM T2 a ORDER BY a.nome collate pt_pt<\/pre><\/div>\n\n\n\n<p>Agora o outro:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:false,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;sql&quot;,&quot;mime&quot;:&quot;text\/x-sql&quot;,&quot;theme&quot;:&quot;default&quot;,&quot;lineNumbers&quot;:true,&quot;styleActiveLine&quot;:true,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;TrpContentRestriction&quot;:{&quot;restriction_type&quot;:&quot;exclude&quot;,&quot;selected_languages&quot;:[],&quot;panel_open&quot;:true},&quot;language&quot;:&quot;SQL&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;sql&quot;}\">SELECT * FROM T2 a ORDER BY a.nome collate pt_br<\/pre><\/div>\n\n\n\n<p>Os collates est\u00e3o atrelados ao charset porque sem eles, o banco n\u00e3o teria a regionalidade de ordena\u00e7\u00e3o, ou quais sinais diacr\u00edticos s\u00e3o iguais a suas vers\u00f5es sem esses sinais e assim por diante.<\/p>\n\n\n\n<p>Mesmo que um banco de dados tenha uma tabela usando 3 <em>charsets <\/em>diferentes, contendo os mesmos dados, o <em>collate <\/em>poder\u00e1 fazer com que os dados se comportem usando a mesma regra lingu\u00edstica. Por exemplo, para o brasil, <em>case\/accent insensitive <\/em>significa que o <em>collate <\/em>n\u00e3o far\u00e1 distin\u00e7\u00e3o entre mai\u00fasculos e min\u00fasculos e que a ordena\u00e7\u00e3o seguir\u00e1 um mesmo padr\u00e3o.<\/p>\n\n\n\n<p>Vamos testar se a ordena\u00e7\u00e3o foi influenciada pelo <em>charset <\/em>executando esta query:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:false,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;sql&quot;,&quot;mime&quot;:&quot;text\/x-sql&quot;,&quot;theme&quot;:&quot;default&quot;,&quot;lineNumbers&quot;:true,&quot;styleActiveLine&quot;:true,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;TrpContentRestriction&quot;:{&quot;restriction_type&quot;:&quot;exclude&quot;,&quot;selected_languages&quot;:[],&quot;panel_open&quot;:true},&quot;language&quot;:&quot;SQL&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;sql&quot;}\">execute block\nreturns(\n  iso8859_1 varchar(10),\n  win1252 varchar(10),\n  unicode varchar(10))\nas\nbegin\n  --iso8859_1\n  iso8859_1='Sim';\n  win1252='-';\n  unicode='-';\n  suspend;\n  for select\n    a.fruta_iso8859, a.fruta_win1252, a.fruta_unicode\n    from T1 a\n    order by a.fruta_iso8859\n    into iso8859_1, win1252, unicode\n  do begin\n    suspend;\n  end\n  -- win1252\n  iso8859_1='-';\n  win1252='Sim';\n  unicode='-';\n  suspend;\n  for select\n    a.fruta_iso8859, a.fruta_win1252, a.fruta_unicode\n    from T1 a\n    order by a.fruta_win1252\n    into iso8859_1, win1252, unicode\n  do begin\n    suspend;\n  end\n  -- unicode\n  iso8859_1='-';\n  win1252='-';\n  unicode='Sim';\n  suspend;\n  for select\n    a.fruta_iso8859, a.fruta_win1252, a.fruta_unicode\n    from T1 a\n    order by a.fruta_unicode\n    into iso8859_1, win1252, unicode\n  do begin\n    suspend;\n  end\nend\n<\/pre><\/div>\n\n\n\n<p>Notamos na sa\u00edda do comando execute block que a ordena\u00e7\u00e3o pelo charset iso8859_1 (latin1), win1252 ou unicode n\u00e3o teve diferen\u00e7a!<\/p>\n\n\n\n<p>Vamos complicar e inserir caracteres n\u00e3o acentuados, executando essa sequencia de ExecSQL:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:false,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;sql&quot;,&quot;mime&quot;:&quot;text\/x-sql&quot;,&quot;theme&quot;:&quot;default&quot;,&quot;lineNumbers&quot;:true,&quot;styleActiveLine&quot;:true,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;TrpContentRestriction&quot;:{&quot;restriction_type&quot;:&quot;exclude&quot;,&quot;selected_languages&quot;:[],&quot;panel_open&quot;:true},&quot;language&quot;:&quot;SQL&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;sql&quot;}\">INSERT INTO T1 (FRUTA_ISO8859, FRUTA_WIN1252, FRUTA_UNICODE)\n            VALUES ('Maracuja', 'Maracuja', 'Maracuja');\nINSERT INTO T1 (FRUTA_ISO8859, FRUTA_WIN1252, FRUTA_UNICODE)\n            VALUES ('A\u00e7ai', 'A\u00e7ai', 'A\u00e7ai');\nINSERT INTO T1 (FRUTA_ISO8859, FRUTA_WIN1252, FRUTA_UNICODE)\n            VALUES ('Gravata', 'Gravata', 'Gravata');\nINSERT INTO T1 (FRUTA_ISO8859, FRUTA_WIN1252, FRUTA_UNICODE)\n            VALUES ('Avela', 'Avela', 'Avela');\nINSERT INTO T1 (FRUTA_ISO8859, FRUTA_WIN1252, FRUTA_UNICODE)\n            VALUES ('Melao', 'Melao', 'Melao');\nINSERT INTO T1 (FRUTA_ISO8859, FRUTA_WIN1252, FRUTA_UNICODE)\n            VALUES ('Ma\u00e7a', 'Ma\u00e7a', 'Ma\u00e7a');\nINSERT INTO T1 (FRUTA_ISO8859, FRUTA_WIN1252, FRUTA_UNICODE)\n            VALUES ('Mamao', 'Mamao', 'Mamao');\nINSERT INTO T1 (FRUTA_ISO8859, FRUTA_WIN1252, FRUTA_UNICODE)\n            VALUES ('Jilo', 'Jilo', 'Jilo');\nINSERT INTO T1 (FRUTA_ISO8859, FRUTA_WIN1252, FRUTA_UNICODE)\n            VALUES ('Babacu', 'Babacu', 'Babacu');\n<\/pre><\/div>\n\n\n\n<p>Executamos o <em>execute block<\/em> outra vez e notamos que n\u00e3o houve diferen\u00e7a, a ordem foi a mesma para todos os casos, apenas a vers\u00e3o n\u00e3o acentuada teve preced\u00eancia.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Este artigo ainda est\u00e1 em rascunho, as informa\u00e7\u00f5es est\u00e3o corretas, mas falta ajustes na formata\u00e7\u00e3o, concord\u00e2ncia gramatical e achar uma maneira mais did\u00e1tica. Mas se entender, pode utiliz\u00e1-lo. Se voc\u00ea usa o Windows, voc\u00ea deve estar se perguntando porque essa pergunta \u00e9 importante.Por gentileza abra o cmd e execute comigo o comando \u2018chcp\u2019, ele retorna [&hellip;]<\/p>\n","protected":false},"author":4,"featured_media":0,"parent":1109,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"templates\/template-full-width.php","meta":{"footnotes":""},"class_list":["post-1132","page","type-page","status-publish","hentry"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/gladiston.net.br\/en\/wp-json\/wp\/v2\/pages\/1132","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/gladiston.net.br\/en\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/gladiston.net.br\/en\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/gladiston.net.br\/en\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/gladiston.net.br\/en\/wp-json\/wp\/v2\/comments?post=1132"}],"version-history":[{"count":9,"href":"https:\/\/gladiston.net.br\/en\/wp-json\/wp\/v2\/pages\/1132\/revisions"}],"predecessor-version":[{"id":2042,"href":"https:\/\/gladiston.net.br\/en\/wp-json\/wp\/v2\/pages\/1132\/revisions\/2042"}],"up":[{"embeddable":true,"href":"https:\/\/gladiston.net.br\/en\/wp-json\/wp\/v2\/pages\/1109"}],"wp:attachment":[{"href":"https:\/\/gladiston.net.br\/en\/wp-json\/wp\/v2\/media?parent=1132"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}