
Assim como versionamos o código fonte, é uma boa prática versionar scripts de banco de dados.
Na minha carreira, muitas empresas alteraram estruturas de banco de dados usando ferramentas de banco de dados, como Dbeaver, Datagrip, SQL Developer ...
Em algumas equipes, após terminar a tarefa do desenvolvedor, os DBAs comparam o banco de dados do desenvolvedor com o banco de dados de produção e aplicam essas mudanças ou
eles salvam o script que foi criado e executado durante a tarefa de desenvolvimento no código fonte, esse script é tão simples quanto MyTable.sql, e será executado manualmente em todos os ambientes.
Uma forma mais fácil é usar a abordagem de migração, na qual todos os artefatos de banco de dados são versionados junto com o código da aplicação.
Para evitar manter scripts sem alguém controlando ferramentas de versão, ou alterando o banco de dados usando ferramentas de edição de schema como mencionado antes, podemos fazer isso através de migrações de script. Cada script pode representar mudanças de schema, mudanças de código de banco de dados, atualizações de dados de transação, correções... Em outras palavras DDL e DML.
Vamos ver um exemplo:
Neste script abaixo criei uma tabela para armazenar clientes.
CREATE TABLE CLIENTS(
ID uuid PRIMARY KEY,
VERSION INTEGER NOT NULL,
NAME VARCHAR(200) NOT NULL,
EMAIL VARCHAR(200) NOT NULL,
STATE VARCHAR(200) NOT NULL,
TYPE VARCHAR(200) NOT NULL,
PHONE_NUMBER_ATTRIBUTES VARCHAR(200) NOT NULL,
BILLING_ATTRIBUTES JSONB NOT NULL,
CREATED_AT TIMESTAMP WITH TIME ZONE NOT NULL,
LAST_MODIFIED_AT TIMESTAMP WITH TIME ZONE NOT NULL
)
Mas depois de algum tempo percebi que também precisava armazenar os agendamentos dos clientes, então vamos usar o poder da migração.
Criando um segundo arquivo de script temos por enquanto:
ALTER TABLE CLIENTS ADD COLUMN APPOINTMENT_ATTRIBUTES JSONB NOT NULL;
Após executar o primeiro e segundo scripts usando uma ferramenta de migração, neste caso, o Flyway, podemos ver que ambas as situações são armazenadas em uma tabela responsável pela auditoria.
No caso do Flyway, a tabela é flyway_schema_history
SELECT * FROM flyway_schema_history;
Usando essa abordagem, todas as mudanças são feitas por migrações. Então, nunca devemos usar ferramentas de banco de dados para edições, como Dbeaver, Datagrip e SQL Developer para executar scripts DML e DDL.
Cada migração precisa de uma identificação única, precisamos rastrear cada migração que foi aplicada, e precisamos gerenciar a sequência de cada migração, para isso, o flyway_schema_history armazena alguns dados como:
Assim, podemos adicionar nosso script de migração como uma etapa do nosso CI como nosso código

Testar scripts de migração localmente, com um teste de integração por exemplo, antes de executar os scripts de migração no CI para entregar no ambiente sandbox e consequentemente no ambiente de produção, é uma boa prática.
Afinal, teremos todo o caminho executado desde a criação dos scripts até a produção passando pelo pipeline (CI) e com muitas opções para testar a nova funcionalidade.
Em algumas equipes com que trabalhei, havia outra opção para executar scripts de migração rodando fora do CI, antes de fazer deploy, desenvolvedores executam o script de migração na sua estação de trabalho localmente.
Ferramentas de migração são uma ótima opção, existem outras opções como Liquibase.
