Bem ... Huh. Durante anos, ninguém mencionou uma coisa sutil.
Apesar de DROP TABLE IF EXISTS `bla`; CREATE TABLE `bla` ( ... );
parecer razoável, isso leva a uma situação em que a tabela antiga já se foi e a nova ainda não foi criada: alguns clientes podem tentar acessar a tabela de assuntos nesse momento.
A melhor maneira é criar uma tabela nova e trocá-la por uma antiga (o conteúdo da tabela é perdido):
CREATE TABLE `bla__new` (id int); /* if not ok: terminate, report error */
RENAME TABLE `bla__new` to `bla`; /* if ok: terminate, report success */
RENAME TABLE `bla` to `bla__old`, `bla__new` to `bla`;
DROP TABLE IF EXISTS `bla__old`;
- Você deve verificar o resultado
CREATE ...
e não continuar em caso de erro , porque falha significa que outro encadeamento não terminou o mesmo script: porque ele travou no meio ou simplesmente não terminou ainda - é uma boa ideia inspecione as coisas sozinho.
- Em seguida, verifique o resultado primeiro
RENAME ...
e não continue em caso de sucesso : toda a operação foi concluída com êxito; ainda mais, a execução seguinte RENAME ...
pode (e será) insegura se outro encadeamento já tiver iniciado a mesma sequência (é melhor cobrir este caso do que não, veja a nota de bloqueio abaixo).
- Segundo
RENAME ...
substitui atomicamente a definição da tabela, consulte o
manual do MySQL
para obter detalhes.
- Por fim,
DROP ...
apenas limpa a mesa antiga, obviamente.
Agrupar todas as instruções com algo como SELECT GET_LOCK('__upgrade', -1); ... DO RELEASE_LOCK('__upgrade');
permite apenas invocá-las seqüencialmente sem verificação de erro, mas não acho que seja uma boa ideia: a complexidade aumenta e as funções de bloqueio no MySQL não são seguras para replicação baseada em instruções.
Se os dados da tabela devem sobreviver à atualização da definição da tabela ... No caso geral, é uma história muito mais complexa sobre a comparação das definições da tabela para descobrir diferenças e produzir ALTER ...
instruções apropriadas , o que nem sempre é possível automaticamente, por exemplo, quando as colunas são renomeadas.
Nota lateral 1:
você pode lidar com visualizações usando a mesma abordagem, neste caso, CREATE/DROP TABLE
apenas se transforma em CREATE/DROP VIEW
enquanto RENAME TABLE
permanece inalterado. Na verdade, você pode até transformar a tabela em exibição e vice-versa.
CREATE VIEW `foo__new` as ...; /* if not ok: terminate, report error */
RENAME TABLE `foo__new` to `foo`; /* if ok: terminate, report success */
RENAME TABLE `foo` to `foo__old`, `foo__new` to `foo`;
DROP VIEW IF EXISTS `foo__old`;
Nota lateral 2: Os
usuários do MariaDB devem estar satisfeitos com o CREATE OR REPLACE TABLE/VIEW
assunto, que já se preocupa com o problema do assunto e seus pontos positivos.