Tabelas MERGE

Tabelas MERGE são novas no MySQL Versão 3.23.25. O código ainda está em gamma, mas deve estar razoavelmente estável.

Uma tabela MERGE (também conhecida como tabela MRG_MyISAM) é uma coleção de tabelas MyISAM idênticas que podem ser usada como uma. Você só pode fazer SELECT, DELETE, e UPDATE da coleção de tabelas. Se você fizer um DROP na tabela MERGE, você só está apagando a especificação de MERGE.

Note que DELETE FROM tabela_merge usado sem um WHERE só limpará o mapeamento a tabela, não deletando tudo nas tabeals mapeadas. (Planejamos consertar isto na versão 4.1).

Com tabelas idênticas queremos dizer que todas as tabelas são criadas com informações de colunas e chaves idênticas. Você não pode fundir tabelas nas quais as colunas são empacotadas de forma diferente, não tenham as mesmas colunas ou tenham as chaves em ordem diferente. No entanto, algumas das tabelas podem ser compactadas com myisampack.

Ao criar uma tabela MERGE, você obterá uma arquivo de definição de tabela .frm e um arquivo de lista de tabela .MRG. O arquivo .MRG contém apenas a lista de arquivos índices (arquivos .MYI) que devem ser usados como um. Antes da versão 4.1.1, todas as tabelas usadas devem estar no mesmo banco de dados assim como a própria tabela MERGE.

Atualmente você precisa ter os privilégios SELECT, UPDATE e DELETE em tabelas mapeadas para uma tabela MERGE.

Tabelas MERGE podem ajudá-lo a resolver os seguintes problemas:

  • Facilidade de gernciamento de um conjunto de log de tabelas. Por exemplo, você pode colocar dados de meses diferentes em arquivos separadosfrom different months into separate files, compress some of them with myisampack, and then create a MERGE to use these as one.
  • Lhe da maior velocidade. Você pode separar uma grande tabela somente leitura baseado em algum critério e então colocar as diferentes partes da tabela em discos diferentes. Uma tabela MERGE desta forma pode ser muito mais rápida que se usada em uma grande tabela. (Você pode, é claro, usar também um nível RAID para obter o memo tipo de benefício.)
  • Faz pesquisas mais eficientes. Se você sabe exatamente o que você esta procurando, você pode buscar em apenas um dos pedaços da tabelas para algumas pesquisas e utilizar tabelas MERGE para outras. Você pode até ter diferentes tabelas MERGE ativas, com possíveis arquivos sobrepostos.
  • Reparações mais eficientes. É facil reparar os arquivos individuais que são mapeados para um arquivo MERGE que tentar reparar um arquivo realmente grande.
  • Mapeamento instantâneo de diversos arquivos como um. Uma tabela MERGE usa o índice de tabelas individuais. Não é necessário manter um índice de para ela. Isto torna a coleção de tabelas MERGE MUITO rápido de fazer ou remapear. Note que você deve especificar a definição de chave quando você cria uma tabela MERGE!.
  • Se você tem um conjunto de tabelas que você junta a uma tabela grande por demanda ou bacth, você deveria criar uma tabela MERGE delas por demanda. Isto é muito mais rápido é economizará bastante espaço em disco.
  • Contornam o limite de tamanho de arquivos do sistema operacional.
  • Você pode criar um apelido/sinônimo para uma tabela usando MERGE sobre uma tabela. Não deve haver nenhum impacto notável na performance ao se fazer isto (apenas algumas chamadas indiretas e chamadas de memcpy() para cada leitura).

As desvantagens de tabelas MERGE são:

  • Você só pode utilizar tabelas MyISAM idênticas em uma tabela MERGE.
  • REPLACE não funciona.
  • Tabelas MERGE usam mais descritores de arquivos. Se você estiver usando uma tabela MERGE que mapeia mais de 10 tabelas e 10 usuários a estão usando, você está usando 10*10 + 10 descritores de arquivos. (10 arquivos de dados para 10 usuários e 10 arquivos de índices compartilhados).
  • A leitura de chaves é lenta. Quando você faz uma leitura sobre uma chave, o mecanismo de armazenamento MERGE precisará fazer uma leitura em todas as tabelas para verificar qual casa melhor com a chave dada. Se você então fizer uma “leia próximo”, o mecanismo de armazenamento MERGE precisará procurar os buffers de leitura para encontrar a próxima chave. Apenas quando um buffer de chaves é usado, o mecanismo de armazenamento precisará ler o próximo bloco de chaves. Isto torna as chaves MERGE mais lentas em pesquisas eq_ref, mas não em pesquisas ref.
  • Você não pode fazer DROP TABLE, ALTER TABLE, DELETE FROM nome_tabela sem uma cláusula WHERE, REPAIR TABLE, TRUNCATE TABLE, OPTIMIZE TABLE, ou ANALYZE TABLE em nenhuma das tabelas que é mapeada por uma tabela MERGE que está “aberta”. Se você fizer isto, a tabela MERGE pode ainda se referir a tabela original e você obterá resultados inexperados. O modo mais fácil de contornar esta deficiência e através do comando FLUSH TABLES, assegurando que nenhuma tabela MERGE permanecerá “aberta”.

Quando você cria uma tabela MERGE você deve especificar com UNION=(lista-de-tabelas) quais tabelas você quer usar com uma. Opcionalmente você pode especificar com INSERT_METHOD se você quer que inserções em tabelas MERGE ocorram na primeira ou na última tabela da lista UNION. Se você não especificar INSERT_METHOD ou especificar NO, entaão todos os comandos INSERT na tabela MERGE retornarão um erro.

O seguinte exemplo lhe mostra como utilizaqr tabelas MERGE:

CREATE TABLE t1 (a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, message CHAR(20));
CREATE TABLE t2 (a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, message CHAR(20));
INSERT INTO t1 (message) VALUES ("Testing"),("table"),("t1");
INSERT INTO t2 (message) VALUES ("Testing"),("table"),("t2");
CREATE TABLE total (a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, message CHAR(20))
             TYPE=MERGE UNION=(t1,t2) INSERT_METHOD=LAST;
SELECT * FROM total;

Note que não criamos uma chave UNIQUE ou PRIMARY KEY na tabela total já que a chave não será única na tabela total.

Note que você também pode manipular o arquivo .MRG diretamente de fora do servidor MySQL:

shell> cd /mysql-data-directory/current-database
shell> ls -1 t1.MYI t2.MYI > total.MRG
shell> mysqladmin flush-tables

Agora você pode fazer coisas como:

mysql> SELECT * FROM total;
+---+---------+
| a | message |
+---+---------+
| 1 | Testing |
| 2 | table   |
| 3 | t1      |
| 1 | Testing |
| 2 | table   |
| 3 | t2      |
+---+---------+

Note que a coluna a, declarada como PRIMARY KEY, não é unica, já que tabelas MERGE não podem forca a unicidade sobre um conjunto de tabelas MyISAM selecionadas.

Para remapear uma tabela MERGE você pode fazer o seguinte:

  • Fazer um DROP na tabela e recriá-la
  • Usar ALTER TABLE nome_tabela UNION=(...)
  • Alterar o arquivo .MRG e executar um FLUSH TABLE na tabela MERGE e todas as tabelas selecionadas para forçar o mecanismo de armazenamento a ler o novo arquivo de definição.

Problemas com Tabelas MERGE

Segue abaixo os problemas conhecidos com tabelas MERGE:

  • Uma tabela MERGE não pode manter restrições UNIQUE sobre toda tabela. Quando você faz um INSERT, os dados vão para a primeira ou última tabela (de acordo com INSERT_METHOD=xxx) e estas tabelas MyISAM asseguram que os dados são únicos, mas não se sabe nada sobre outras tabelas MyISAM.
  • DELETE FROM tabela_merge usado sem um WHERE só limpará o mapeamento da tabela, não deletando tudo na tabela mapeada.
  • RENAME TABLE em uma tabela usada por uma tabela MERGE ativa pode corromper a tabela. Isto será corrigido no MySQL 4.1.x.
  • Criação de uma tabela do tipo MERGE não verifica se o tabelas selecionadas são de tipos compatíveis ou se elas existem. O MySQL fará uma verificação rápida de se o tamanho do registro é igual entre tabelas mapeadas quando a tabela MERGE é usada, mas esta não é uma verificação total.

Se você usar tabelas MERGE deste modo, você poderá obter problemas estranhos.

  • Se você usar ALTER TABLE para adicionar primeiro um índice UNIQUE em uma tabela usada em uma tabela MERGE e então usar ALTER TABLE para adicionar um índice normal na tabela MERGE, a ordem da chave será diferente para as atabelas se houvesse uma chave não única antiga na tabela. Isto ocorre porque ALTER TABLE coloca chaves UNIQUE antes de chaves normais para estar apto a detectar chaves duplicadas o mais rápido possível.
  • DROP TABLE em uma tabela que está em uso por uma tabela MERGE não funcionará no Windows porque o mecanismo de armazenamento MERGE faz o mapeamento da tabela escondido da camada mais alta do MySQL. Como o Windows não permite que você apague arquivos que estejam abertos, você deve primeiro descarregar todas as tabelas MERGE (com FLUSH TABLES) ou apagar a tabela MERGE antes de apagar a tabela. Nós consertaremos isto assim que introduzirmos VIEWs.

Tabelas ISAM

O tipo de tabela ISAM, obsoleto, desaparecerá na versão 5.0. Ele está incluído no fonte do MySQL 4.1 é mas não é mais compilado. MyISAM é uma implementação melhor deste handler de tabela e você deve converter todas as tabelas ISAM para tabelas MySAM o mais rápido possível.

ISAM usa um índice B-tree. O índice é armazenado em um arquivo com a extensão .ISM, e os dados são armazenados em um arquivo com a extensão .ISD. Você pode verificar/reparar tabelas ISAM com o utilitário isamchk.

ISAM tem os seguintes recursos/propriedades:

  • Chaves compactadas e de tamanho fixo.
  • Registros de tamanho fixo e dinâmico
  • 16 chaves com 16 chaves parciais/chaves
  • Tamanho máximo da chave de 256 (padrão)
  • Os dados são armazenados em formato de máquina; isto é rápido mas é dependente da maquina/SO.

A maioria das coisas que são verdadeiras para tabelas MyISAM também são verdadeiras para tabelas ISAM. As maiores diferenças comparados a tabelas MyISAM são:

  • Tabelas ISAM não são bninários portáveis entre SO/Pataformas.
  • Não pode lidar com tabelas > 4G.
  • Só suporta compactação de prefixo em strings.
  • Limite de chaves menor.
  • Tabelas dinâmicas são mais fragmentadas.
  • Tableas são compactadas com pack_isam ao invés de myisampack.

Se você quiser converter uma tabela ISAM em uma tabela MyISAM de forma a se poder utilizar utilitários tais como mysqlcheck, use uma instrução ALTER TABLE:

mysql> ALTER TABLE nome_tabela TYPE = MYISAM;

A versões embutidas do MySQL não supoortam tabelas ISAM.

Tabelas HEAP

Tabeals HEAP usam índices hash e são armazenadas na memória. Isto as torna muito rápidas, mas se o MySQL falhar você irá perder todos os dados armazenados nela. HEAP é muito útil para tabelas temporárias!

As tabelas HEAP do MySQL utilizam hashing 100% dinâmico sem áreas em excesso. Não há espaços extras necessários para listas livres. Tabelas HEAP também não têm problemas com deleção + inserção, o que normalmente é comum em tabelas com hash:

mysql> CREATE TABLE test TYPE=HEAP SELECT ip,SUM(downloads) AS down
    ->                   FROM log_table GROUP BY ip;
mysql> SELECT COUNT(ip),AVG(down) FROM test;
mysql> DROP TABLE test;

Aqui seguem algumas coisas que você deve considerar ao utilizar tabelas HEAP:

  • Você sempre deve utilizar a especificação MAX_ROWS na instrução CREATE para assegurar que você não irá utilizar toda a memória acidentalmente.
  • Índices só serão utilizados com = e <=> (mas é MUITO rápido).
  • Tabelas HEAP só podem usar chaves inteiras para procurar por uma linha; compare isto a tabelas MyISAM onde qualquer prefixo de chave pode ser usada para encontrar linhas.
  • Tabelas HEAP usam um formato de registro de tamanho fixo.
  • HEAP não suporta colunas BLOB/TEXT.
  • HEAP não suporta colunas AUTO_INCREMENT.
  • Antes do MySQL 4.0.2, HEAP não suportava um índice em uma coluna NULL.
  • Você pode ter chaves não únicas em uma tabela HEAP (isto não é comum em tabelas com hash).
  • Tabelas HEAP são compartilhadas entre todos os clientes (como qualquer outra tabela).
  • Você não pode pesquisar pela próxima entrada na ordem (isto é, usar o índice para fazer um ORDER BY).
  • Dados de tabelas HEAP são alocados em blocos menores. As tabelas são 100% dinâmicas (na inserção). Não são necessárias areas excessivas e espaço de chave extra. Linhas deletadas são colocadas em uma lista encadeada e são reutilizadas quando você insere novos dados na tabela.
  • Você precisa de memória extra suficiente para todas as tabelas HEAP que você quiser utilizar ao mesmo tempo.
  • Para liberar memória, você deve executar DELETE FROM tabela_heap, TRUNCATE tabela_heap ou DROP TABLE tabela_heap.
  • O MySQL não pode descobrir aproximadamente quantas linhas existem entre dois valores (isto é utilizado pela atimizador de escala para decidar qual indice usar). Isto pode afetar algumas consultas se você alterar uma tabela MyISAM para uma tabela HEAP.
  • Para assegurar que você não vai cometer nenhum erro acidentalmente, você não pode criar tabelas HEAP maiores que max_heap_table_size.

A memória necessária para uma linha na tabela HEAP é:

SUM_OVER_ALL_KEYS(max_length_of_key + sizeof(char*) * 2)
+ ALIGN(length_of_row+1, sizeof(char*))

sizeof(char*) é 4 em uma máquina de 32 bits e 8 em uma máquina de 64 bits.

Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s