Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

ALTER TABLE no MySQL:amigo ou inimigo?

A instrução ALTER TABLE é uma das instruções mais usadas no mundo MySQL - a instrução permite adicionar, excluir ou modificar colunas em uma tabela. Nesta postagem do blog, tentaremos nos aprofundar no que é, o que faz e quando deve ser usado.

O que é ALTER TABLE e o que ele faz?

Como já mencionado acima, a instrução ALTER TABLE permite que DBAs e desenvolvedores adicionem, excluam ou modifiquem colunas em uma tabela. Basta colocar ALTER TABLE altera a estrutura de uma tabela - permite adicionar, excluir colunas, adicionar ou remover índices, renomear colunas ou alterar seu tipo.

Quando e como usar ALTER TABLE?

Para usar ALTER TABLE você geralmente precisa dos privilégios ALTER, CREATE e INSERT. Para renomear uma tabela, os privilégios necessários são ALTER e DROP para a tabela antiga, depois os privilégios CREATE, ALTER e INSERT para a nova tabela a ser criada. Para atribuir os privilégios necessários a um determinado usuário, você pode usar a seguinte consulta:

GRANT ALTER, CREATE, INSERT ON database.* TO 'demo_user';

Substitua database pelo nome do seu banco de dados, o curinga pelo nome da tabela se desejar que os privilégios sejam aplicáveis ​​apenas a determinadas tabelas (o curinga torna o privilégio aplicável a todas as tabelas) e demo_user pelo nome de seu usuário. Se você quiser que os privilégios sejam usados ​​em todos os bancos de dados e todas as tabelas dentro deles, basta substituir database por um curinga:

GRANT ALTER, CREATE, INSERT ON *.* TO 'demo_user';

Para realmente usar a instrução ALTER TABLE, execute uma consulta que altera a estrutura de uma tabela - ALTER TABLE é usado para adicionar, excluir ou modificar colunas em uma tabela:a consulta também pode ser usado para adicionar índices a colunas. Aqui estão alguns exemplos básicos de consultas usadas com mais frequência:

ALTER TABLE demo_table ADD column_name VARCHAR(255) NOT NULL DEFAULT ‘’; T

sua consulta adicionaria uma coluna column_name a uma tabela demo_table. Adicione FIRST ao final da consulta para tornar a coluna a primeira coluna na tabela.

ALTER TABLE demo_table ADD column_2 VARCHAR(255) NOT NULL DEFAULT ‘’ AFTER column_1; T

sua consulta adicionaria uma coluna column_2 após a coluna column_1 em uma tabela demo_table.

ALTER TABLE demo_table ADD COLUMN column_2 INT GENERATED ALWAYS AS (column_1 + 1) STORED; 

Esta consulta adicionaria uma coluna gerada à tabela.

ALTER TABLE demo_table DROP COLUMN demo_column; 

Esta consulta eliminaria a coluna demo_column em uma tabela demo_table.

ALTER TABLE demo_table ADD INDEX demo_index(demo_column); 

Esta consulta adicionaria um índice chamado demo_index (os nomes podem ser escolhidos) em uma coluna chamada demo_column em uma tabela chamada demo_table.

ALTER TABLE demo_table ADD INDEX (demo_column), ADD UNIQUE (demo_unique); 

Esta consulta adicionaria um índice em uma coluna demo_column e um índice exclusivo na coluna demo_unique.

ALTER TABLE demo_table MODIFY column_name VARCHAR(255) CHARACTER SET utf8mb4; 

Esta consulta alteraria o conjunto de caracteres padrão de uma coluna específica.

ALTER TABLE demo_table CONVERT TO CHARACTER SET charset_name; 

Esta consulta alteraria o conjunto de caracteres padrão da tabela e todas as colunas de caracteres (CHAR, VARCHAR e TEXT).

ALTER TABLE demo_table PARTITION BY HASH(demo_column) PARTITIONS 8; 

Esta consulta dividiria a coluna demo_column em 8 partições por hash.

ALTER TABLE demo_table TABLESPACE tablespace_1 STORAGE DISK; 

Esta consulta converteria a tabela demo_table em armazenamento baseado em disco.

Se você estiver adicionando índices, lembre-se de que você pode adicionar diferentes tipos de índices (por exemplo, um índice BTREE ou um índice FULLTEXT), você também pode adicionar um índice que cobre apenas uma certa quantidade de caracteres em uma coluna com uma consulta assim:

ALTER TABLE demo_table ADD INDEX demo_index(column_name(10));

A consulta acima adicionaria um índice chamado demo_index nos primeiros 10 caracteres da coluna chamada column_name em uma tabela chamada demo_table.

Os índices no MySQL são uma fera complexa e eles realmente merecem um tópico próprio, então não entraremos em detalhes aqui, mas se você quiser aprender mais, nosso post anterior sobre índices do MySQL deve fornecer alguns mais discernimento.

Como funciona ALTER TABLE?

ALTER TABLE no MySQL tem suas próprias sutilezas. A partir da versão mais atual do MySQL, ou seja, MySQL 8.0. Existem 3 algoritmos que afetam o desempenho de ALTER TABLE para tais alterações. Esses são:


  • CÓPIA DE

    • As operações são executadas em uma cópia da tabela original e os dados da tabela são copiados da tabela original para a nova tabela linha por linha. Na maioria dos casos, esse algoritmo pode ser muito caro em termos de uso de recursos, especialmente para tabelas grandes e grandes. Quando este algoritmo é escolhido ou selecionado, todos os DML simultâneos não são permitidos, portanto, quaisquer consultas subsequentes referentes à tabela afetada terão que esperar ou enfileiradas na lista de processos. As chances são de que seu banco de dados fique travado se as conexões estiverem no limite.

  • NO LUGAR

    • As operações evitam copiar dados da tabela, mas podem reconstruir a tabela no local. Um bloqueio de metadados exclusivo na tabela pode ser feito brevemente durante as fases de preparação e execução da operação. Normalmente, o DML simultâneo é suportado.

  • INSTANTE

    • As operações modificam apenas os metadados no dicionário de dados. Nenhum bloqueio de metadados exclusivo é feito na tabela durante a preparação e execução, e os dados da tabela não são afetados, tornando as operações instantâneas. DML simultâneo é permitido. (Introduzido no MySQL 8.0.12)

O processo ALTER TABLE do MySQL pode não ser um problema com tabelas menores, mas se seu conjunto de dados for maior, você poderá ter problemas - muitas pessoas experimentaram consultas ALTER TABLE que levaram horas, dias ou até semanas completar. Na maioria dos casos, isso acontece por causa do processo de alteração de tabela do MySQL descrito acima. No entanto, existe uma maneira de reduzir pelo menos um pouco o tempo que a consulta leva para ser concluída:

  1. Crie uma nova tabela como sua tabela de origem com a estrutura desejada executando
    CREATE TABLE demo_table_new LIKE demo_table;
    em seguida, ajustando sua estrutura. Nesse caso, demo_table é a tabela de origem e demo_table_new é a nova tabela.
  2. Insira dados na nova tabela.
  3. Renomeie a tabela antiga para demo_table_old (ajuste o nome de acordo com suas necessidades).
  4. Renomeie a nova tabela para o antigo nome da tabela antiga.
  5. Finalmente, copie as linhas da tabela antiga para a nova tabela e, se necessário, crie índices.

Embora as etapas acima funcionem bem. No entanto, em cenários de casos do mundo real, DBAs ou desenvolvedores usam o lean para usar o pt-online-schema-change do Percona ou usar o gh-ost do Github. Você pode dar uma olhada em nosso post anterior Top Open Source Tools for MySQL &MariaDB Migrations que tem uma visão geral dessas ferramentas de mudança de esquema.

De qualquer forma, o que descrevemos acima é frequentemente conhecido como a abordagem de “cópia de sombra”:em essência, você cria uma nova tabela com a estrutura desejada, depois renomeia e remove para trocar as duas tabelas . Também existe outra maneira:você também pode trocar servidores e executar ALTER TABLE em servidores que não estão em produção. Para MyISAM, você pode DESABILITAR TECLAS, carregar dados, então HABILITAR TECLAS.

ALTER TABLE Pegadinhas

Se você estiver usando a instrução ALTER TABLE para criar índices (você também pode usar a instrução CREATE INDEX), é aconselhável criar índices após inserir os dados porque essa é uma maneira bastante conhecida de acelerar processamento não apenas em MySQL, mas também em outros sistemas de gerenciamento de banco de dados, como Oracle. Em geral, porém, tenha em mente que a maioria das operações ALTER TABLE deve causar alguns problemas (interrupção de serviço) ao MySQL.

Há também outra maneira de acelerar todo o processo, embora seja um pouco mais avançado:se você puder convencer o MySQL a modificar apenas o arquivo .frm da tabela (arquivos .frm descrevem a definição de a tabela) e deixe a tabela em paz, o processo será mais rápido:

  1. Crie uma tabela vazia com o mesmo layout da tabela antiga sem modificá-la.
  2. Feche todas as tabelas em uso e impeça que todas as novas tabelas sejam abertas executando 
    FLUSH TABLES WITH READ LOCK.
  3. Troque os arquivos .frm.
  4. Libere o bloqueio de leitura executando UNLOCK TABLES.

Lembre-se também de que, se você deseja modificar uma coluna e a sintaxe parece correta, mas ainda ocorre um erro, talvez seja hora de procurar uma sintaxe diferente. Por exemplo:

ALTER TABLE demo_table ADD long VARCHAR(255); 

Uma consulta como essa apresentaria um erro porque long é uma palavra reservada. Para evitar esse erro, escape a palavra com acentos graves:

ALTER TABLE demo_table ADD `long` VARCHAR(255);

Também vale a pena notar que os nomes das colunas só podem ser escapados usando acentos graves e não com aspas simples ou aspas duplas. Por exemplo, uma consulta como essa também apresentaria um erro:

ALTER TABLE demo_table CHANGE COLUMN ‘demo_column’ ‘demo_column_2’ VARCHAR(255);

Resumo


O MySQL usa a instrução ALTER TABLE para adicionar, excluir ou modificar colunas em uma tabela. Para que a instrução seja executada com sucesso, você deve ter os privilégios ALTER, CREATE e INSERT para a tabela. A instrução também tem algumas sutilezas exclusivas:seu desempenho pode ser prejudicado ao ser executado em tabelas muito grandes devido à maneira como funciona, mas contanto que você saiba como a instrução funciona e o que ela faz, você deve estar bem.