Posts Tagged ‘ MySQL ’

Varchar ou Char?

Quando as pessoas criam as tabelas num banco de dados, parece unânime a escolha de ‘varchar’ para representar strings e texto curto em geral. Em pouquíssimos lugares vê-se o uso de ‘char’.

Para coisas maiores, acabam usando algo como ‘text’ ou ‘longtext’ (nomenclatura do MySQL, pode variar), que permite, em geral, até 64KB e até 2GB de texto, respectivamente.

– Por que isso é feito assim?

O varchar é um tipo existente em, possivelmente, todo banco de dados, e guarda apenas a quantidade de caracteres do texto armazenado, sem adicionar espaços em branco. Por exemplo, se temos um campo varchar(40), ele vai armazenar fisicamente de 0 a 40 bytes, dependendo do tamanho do texto inserido.

Já o tipo ‘char’, aloca espaço para todos os caracteres, deixando bytes vazios. No caso de char(40), o banco de dados vai ter exatamente 40 bytes por linha naquela coluna.

O tipo ‘text’, assim como suas variações, usa a mesma ideia do ‘varchar’, mas é feito para quantidades maiores de texto.

Veja como é o design da tabela de posts de um blog WordPress:

Veja que os tipos usados para armazenar texto são 'varchar', 'text' e 'longtext'.

Parece meio óbvio que usar um campo variável para armazenar texto é mais interessante que um campo fixo, já que poupa espaço desnecessário, no entanto, em termos de performance usar varchar pode transformar sua aplicação numa carroça.

Um banco de dados armazena seus dados em páginas de tamanho fixo, sendo que os bancos modernos usam páginas de 16KB (maioria) ou 32KB (IBM DB2). Alguns ainda usam páginas menores, como o Microsoft Access (4KB) ou o Microsoft SQL 2000 (8KB).

Desta forma, quando você adiciona uma linha numa tabela de um Banco, ele vai procurar a próxima página que tenha espaço suficiente e vai escrever seus dados lá.

Abaixo temos um exemplo de uma linha sendo adicionada à uma página que estava vazia. O ponto azul é para mostrar que naquele ponto tem um ‘varchar’ que foi criado vazio.

Quando usamos um tipo de dados como ‘varchar’, a linha adicionada numa tabela pode crescer se um dia resolvermos colocar mais dados. Imagine que você está fazendo o cadastro de usuários e o campo de endereço da pessoa (varchar(200), por exemplo) foi criado sem nada escrito.

Antes que o usuário resolva adicionar seu endereço ao cadastro, outros usuários se inscreveram no sistema e, como seus dados cabiam na mesma página anterior, foram colocados juntos:

Assim, quando o primeiro usuário adiciona seu endereço ao cadastro, a página onde os dados dele estavam já não tem mais espaço.

A solução que o banco dá é de colocar o novo dado no lugar certo e empurrar o excedente para a próxima página que tenha espaço livre. Além disso, ele cria um ponteiro da primeira página para a segunda, mostrando que, sempre que for preciso ler os dados do último usuário, ele tenha que acessar duas páginas:

– Qual o problema disso?

Para entender o porquê disso ser algo ruim é preciso saber que o banco de dados, por mais que armazene tudo em disco, ele precisa fazer o mínimo possível de acessos ao disco, para manter uma performance boa.

Tempos de acesso em Processador 32-bit rodando à 2.0GHz

Pela tabela acima, vemos que o tempo que o processador precisa esperar para que um dado do HD chegue à ele é mais de 140.000 vezes maior que pegar um dado da memória. Assim, usando uma página de 32KB e lendo em blocos de 512B (No final de 2009, HDs de blocos de 2KB começaram a ser padrão), o tempo gasto para fazer essa leitura pode ser muito grande, ainda mais se as duas páginas não estiverem fisicamente próximas.

– Então, vale a pena economizar espaço e depois ficar com um banco lento?

Algumas vezes esse problema não vai ser percebido, talvez pela aplicação não ser grande o suficiente ou talvez por não haver atualização nos dados.

Se for sabido de antemão que não haverá mudança numa linha após a sua criação, então não há problema algum em usar Varchar.

– Mas vale a pena correr o risco?

Vamos ver: Digamos que eu tenha uma tabela com 10 campos do tipo varchar(40) e a previsão é de que essa tabela receba até 10 milhões de linhas.

Dependendo dos dados, o tamanho da minha tabela pode variar de 10MB até 410MB, já que o Varchar armazena 1 byte para sinalizar o tamanho utilizado, que é menor ou igual a 40.

Isso quer dizer que, mesmo com uma tabela ENORME, eu só vou economizar uns 100 ou 200MB de espaço em disco!

Quanto custa um terabyte hoje? 2000 Reais? 1000 Reais?
Não, 200 Reais ou menos.

Por outro lado, se o seu texto for grande (> 255B) ou tiver uma grande variação de tamanho (desde 1 ou 2KB até 100 ou 200KB), é interessante utilizar um campo variável, como é o ‘text’ e o ‘longtext’ do MySQL.

Anúncios