Back-End

17 jul, 2008

Os Tipos de Dados no MySQL – String

Publicidade

Continuando nosso estudo sobre os tipos de dados suportados pelo MySQL 5.0, quando começamos apresentando os tipos numéricos, neste artigo discutiremos os tipos de dados string, ou seja, apresentaremos todos os tipos de dados string – binários e não-binários – bem como conjuntos de caracteres – CHARSET – e seus conjuntos de regras de comparação de caracteres – COLLATION. Sabendo-se que cada CHARSET disponível no MySQL 5.0 tem necessidadesde armazenamento diferentes, abordaremos também o espaço necessário para armazenamento de cada valor em uma coluna de uma tabela.

Tipos de Dados String

Os tipos de dados de armazenamento de strings no MySQL 5.0 podem ser binários ou não-binários, ou seja, podem conter somente caracteres ou somente bytes. O que difere os tipos de dados binários de não-binários é que os não-binários são baseados em comparações entre caracteres e os binários são baseados em comparações byte-a-byte.

Tipos de Dados Não-Binários

Os tipos de dados CHAR, VARCHAR, TEXT, TINYTEXT, MEDIUMTEXT e LONGTEXT são tipos de dados não-binários que armazenam seqüências de caracteres disponíveis em um determinado conjunto de caracteres que por sua vez tem também um COLLATE específico (COLLATE ou COLLATION é um conjunto de regras de comparações de strings utilizado para comparar e ordenar caracteres). O conjunto de caracteres pode ser definido no servidor de banco de dados, na criação do banco de dados, na criação da tabela ou na criação da coluna de uma tabela.

Dando atenção à estrutura física a qual o MySQL 5.0 apresenta no sistema operacional, ao criarmos um banco de dados através da linha de comando ou qualquer outra interface, sendo gráfica ou GUI, podemos observar a criação de um arquivo chamado “db” com extensão “.opt” dentro do diretório do banco de dados, sob o diretório de dados. O conteúdo deste arquivo apresenta o CHARACTER SET e o COLLATE do banco de dados, sendo herdado pelas configurações globais do servidor ou informados quando o criamos. A partir disso, todas as tabelas e colunas que omitam um CHARACTER SET e COLLATE na sua sintaxe de criação, utilizarão os globais, setados para o banco de dados. A Figura 1 mostra o arquivo “db.opt“.

Figura 1 - O arquivo \Figura 1 – O arquivo \”db.opt\” que é criado no diretório de banco de dados.

Vejamos como funciona na prática:

Criemos um banco de dados de nome artigo_dt com CHARACTER SET utf8 e COLLATE utf8_general_ci como na Figura 2;

Figura 2 - Criamos a tabela e em seguida emitimos SHOW CREATE TABLE para verificar os atributos.Figura 2 – Criamos a tabela e em seguida emitimos SHOW CREATE TABLE para verificar os atributos.

Após a criação do banco de dados, com o comando SHOW CREATE DATABASE nome_banco podemos verificar que o banco de dados foi criado da maneira como desejamos. Caso o comando de criação do banco de dados omita o CHARACTER SET e o COLLATE, ambos, CHARACTER SET e COLLATE terão seus valores setados para o padrão do servidor que é latin1 e latin1_swedish_ci respectivamente, definidos no arquivo de configuração my.ini (Windows) ou my.cnf (Unix-Like Systems). Independente dos atributos setados para o banco de dados, estes também poderão ser estabelecidos na criação de uma tabela e abordados também em uma coluna, como mostra a Figura 3.

Figura 3 - Independente das opções de CHARACTER SET e COLLATE do banco de dados, tabelas e colunas podem ser configurados.Figura 3 – Independente das opções de CHARACTER SET e COLLATE do banco de dados, tabelas e colunas podem ser configurados.

Observe que o comando SHOW CREATE TABLE nome_tabela exibe como a tabela foi criada e nos mostra que, embora tenhamos definido que o COLLATE global seria utf8_general_ci, criamos uma coluna nesta tabela para armazenar caracteres com um COLLATE que pertence a outro conjunto de caracteres.

Tipos de dados não-binários diferem de tipos de dados binários pois armazenam caracteres e seu espaço é medido em caracteres, além de sua comparação ser baseada em caracteres. Por exemplo, digamos que temos a tabela tab1 com uma coluna chamada NOME e esta coluna tem o seu tipo de dado definido como CHAR(60). Esta coluna armazena 60 caracteres e um byte por caractere. No conjunto de caracteres latin1, esta coluna, ao ser criada com o tipo de dado CHAR, já alocaria seu espaço mínimo de 60 bytes. O conjunto de caracteres utf8 requer entre dois ou três bytes para cada valor, então, para esta coluna, utilizando o conjunto de caracteres utf8, teremos alocado fixamente no arquivo de dados em disco, após a criação da tabela, 180 bytes para cada valor da coluna. Se utilizarmos o conjunto de caracteres ucs2 Unicode, este, por sua vez, requer dois bytes por valor. Mesmo requerendo mais espaço, cada caractere é único ocupando mais de um byte.

Os maiores problemas com CHARACTER SET e COLLATION estão relacionados a diferenciação de maiúsculas e minúsculas e acentuação, pois, alguns conjuntos de caracteres podem ser acent sensitive e outros não.

Podemos tornar uma coluna não-binária e uma coluna binária, atribuindo a ela um COLLATE com terminação bin. A comparação continuaria da mesma maneira, pois cada caractere armazenado de forma binária tem um inteiro que o representa em um conjunto de caracteres, permanecendo a comparação baseada em caracteres, que a partir de agora, teremos strings com diferenciação entre maiúsculas e minúsculas, como segue no exemplo, alterei o collate da coluna NOME para latin1_bin e inseri dois valores que intercalam letras maiúsculas e minúsculas tornando as strings diferentes. Após isso, veja os seguintes SELECT´s, como mostra a Figura 4.

Figura 4 - Strings binárias diferenciam maiúsculas de minúsculas.Figura 4 – Strings binárias diferenciam maiúsculas de minúsculas.

Voltando o campo NOME para latin1_swedish_ci, temos a seguinte situação de não distinção de caso sensitivo entre os valores, como mostra a Figura 5.

Figura 5 - Voltamos o COLLATION para que não haja mais distinção entre maiúsculas e minúsculas.Figura 5 – Voltamos o COLLATION para que não haja mais distinção entre maiúsculas e minúsculas.

Existem três tipos de COLLATION para a maioria dos conjuntos de caracteres: ci, cs e bin, que são, case insensitive, case sensitive e binário respectivamente. Através do comando SHOW COLLATION e SHOW CHARACTER SET se pode verificar os possíveis e quais estão compilados no momento prontos para serem utilizados.

Quando inserimos uma valor qualquer em uma coluna com tipo de dado não-binário e esse valor é menor que a largura da coluna, a coluna é preenchida com espaços em branco e quando solicitamos o retorno da informação com um SELECT esses espaços em branco são removidos automaticamente. Essa regra não se aplica aos tipos não-binários de tamanho variável como VARCHAR.

Existe um grande paradoxo quando o assunto se vira para os tipos de dados CHAR e VARCHAR. O tipo CHAR apresenta tamanho fixo, alçando mais espaço em disco e tem melhor desempenho quando se recupera dados. Por outro lado, o tipo VARCHAR ocupa menos espaço em disco pois não ocupa toda a largura do campo, somente o tamanho da string inserida mais um ou dois bytes dependendo do tamanho da string para armazenar sua quantidade de caracteres (0 à 255 = 1 byte, 256 à 65535 = 2 bytes). Toda vez que informações são lidas para o seu retorno e estas informações vem de campos cujo tipo de dado é VARCHAR, o SGBD lerá seu cabeçalho para verificar o tamanho da string que é armazenada no campo antes de retornar, isso para cada linha/tupla da tabela. Podemos resumir esse paradoxo da seguinte forma: “o que mais lhe importa, que seu banco de dadosd consuma menos espaço em disco ou que sua consulta atenda mais rápido aos seu cliente?“, disco é barato, ter um sistema todo comprometido por má performance pode custar bem mais caro!

Podemos notar que tabelas que utilizam campos com a definição de seu tip de dado VARCHAR, são do tipo dinâmicas. Caso você utilize somente CHAR, elas terão o seu tipo fixo, mais performance na recuperção de dados.

Com toda essa flexibilidade na criação de tabelas no MySQL 5.0, já podemos controlar melhor o ambiente já que, contamos com as variações de conjuntos de caracteres nos quatro níveis, servidor, banco de dados, tabela e coluna.

A Tabela 2, aborda a métrica de requerimento de espaço para armazenamento de cada tipo de dado não-binário:

Tabela 2 - Tipo de dados não-binários.Tabela 2 – Tipo de dados não-binários.

Tipos de Dados Binários

Do lado dos tipos de dados binários suportados pelo MySQL temos os tipos BINARY, VARBINARY, BLOB, TINYBLOB, MEDIUMBLOB e LONGBLOB. São ligeiramente equivalentes aos tipos não-binários e apresentam também suas particularidades.

Colunas que armazenam strings de valores binários são comparados byte-a-byte e não apresentam nenhum CHARACTER SET e COLLATION. São também preenchidas com espaços e este não são removidos quando emitimos um SELECT para retorno dos dados. Espaços em branco não são adicionados ao tipo binário de tamanho variável VARBINARY. Os campos BLOB (BINARY LARGE OBJETS) são utilizados para armazenar arquivos de áudio e fotos, embora seja lento para recuperar tais conteúdos.

A Tabela 3, aborda a métrica de requerimento de espaço para armazenamento de cada tipo de dado binário:

Tabela 3 - Tipos de dados binários.Tabela 3 – Tipos de dados binários.

Um problema que podemos ter com tipos de dado binário é quanto a ordenação – de strings – de uma coluna. Quando é solicitado uma ordenação ascendente, maiúsculas são colocadas à frente de minúsculas, como mostra a Figura 8.

Figura 8 - Ordenação com maiúsculas primeiro e minúsculas depois. Observe que os espaços em braço não foram removidos, ao contrário de campos não-binários.Figura 8 – Ordenação com maiúsculas primeiro e minúsculas depois. Observe que os espaços em braço não foram removidos, ao contrário de campos não-binários.

Tipos de Dados ENUM e SET

Os tipos de dados ENUM e SET são tipos de dados bastante especiais em ocasiões em que temos opções que não mudam ou quase não mudam. É formado, na criação da coluna, por uma lista de possíveis valores que funcionam externamente como várias opções possíveis para a coluna ou para o registro atual. Internamente, o MySQL 5.0 controla as opções como um array, que inicia sua contagem de um. Caso a coluna com um tipo de dado ENUM não tenha uma restrição NOT NULL, ao ser inserido um valor que não costa na lista interna de valores, um valor especial de erro ´´ (vazio) é inserido. Permite a escolha de um valor da lisa por registro, armazenando internamente o seu índice.

A seguinte tabela utiliza uma coluna com o tipo de dado ENUM, como mostra a Figura 9.

Figura 9 - Tabela com uma coluna utilizando o tipo de dado ENUM.Figura 9 – Tabela com uma coluna utilizando o tipo de dado ENUM.

Na tabela acima temos duas situações possíveis, já que a coluna aceita valores nulos e não possui um valor DEFAULT atribuído. Caso um INSERT tente incluir na coluna um valor que não consta na lista de valores do tipo ENUM, um valor ´´ (vazio) será inserido. NULL também será permitido como mostra a Figura 10.

Figura 10 - Após o INSERT de um valor não consta na lista, o resultado é um registro vazio.Figura 10 – Após o INSERT de um valor não consta na lista, o resultado é um registro vazio.

Para evitar que o campo aceite null, altere a estrutura da tabela para NOT NULL. Para não armazenar opções fora da lista informada no tipo da coluna, configure a coluna como NOT NULL DEFAULT ´opção´. Os valores no tipo de dado ENUM requerem um byte para valores de 0 à 255 ou dois bytes para valores de 256 à 65535.

O tipo de dados SET também é um tipo de dado do tipo lista, mas com algumas diferenças do tipo de dado ENUM. SET é armazenado em no máximo oito bytes, permitindo no máximo 64 valores e pode armazenar mais de uma opção da lista de valores configurados na criação da coluna. Criamos uma tabela com uma coluna do tipo SET na Figura 11.

Figura 11 - Criação da tabela com tipo de dado SET.Figura 11 – Criação da tabela com tipo de dado SET.

Conclusão

Nesta parte do estudo de Tipos de Dados do MySQL 5.0, vimos os tiposde dados string, ou seja, que armazenam um conjunto de elementos entre letras, números e símbolos especiais. Vios os tipos de dados string não binários e os binários, al´me de uma breve passagem pelos conjunto de caracteres e collations disponíbveis bem como o espaço de armazenamento necessário para armazenamento.