Implementando Entidades: Scripts Flyway

Introdução

Numa equipe de desenvolvimento de software cada pessoa trabalha com uma versão do código na sua máquina e da mesma forma uma versão do banco de dados. Para o código temos sistemas de controle de versão, mas e para o banco de dados?

Temos uma framework chamada Flyway.

Antes de iniciar

Este item exige conhecimentos sobre:

Criando Scripts Flyway

Seguiremos os campos da entidade Funcionario já criada para descrever os procedimentos.

Siga o checklist abaixo: <table class="table table-bordered">

Qual o nome padrão dos Scripts Flyway? help! Onde devem ficar os Scripts Flyway? help! Como testar os Scripts Flyway? help! Alteração de tabelas no flyway e inserção de index help!

</table>

Qual o nome padrão dos Scripts Flyway?

As migrações SQL devem seguir um padrão de nomenclatura como por exemplo: VTEST.000__Funcionario.sql:

  • V = Prefixo
  • TEST = Nome do projeto
  • 000__ = Versão.
  • Funcionario = Nome da tabela
  • .sql = extensão do arquivo

Importante: NUNCA edite um arquivo existente, ainda que esteje errado. Se for necessário fazer alterações, crie um novo script VTESTS.001__Funcionario.sql que corrija o anterior. É por isto que definimos versões nos nomes de cada arquivo.

Onde devem ficar os Scripts Flyway?

A princípio você deve criar o arquivo VTEST.000__Funcionario.sql no diretório /src/main/resources/ do seu projeto até que seja devidamente revisado.

Após a revisão, mova o script para o diretório /src/main/resources/db/migration/ do seu projeto.

Sabendo o padrão e o diretório do script, vamos criar um para nossa entidade Funcionario.

use NOME_DO_BANCO;	
	
drop table if exists FUNCIONARIO;
		
create table FUNCIONARIO (
		
ID integer not null auto_increment,
NOME varchar(60) not null,
MATRICULA varchar(60) not null,
DATA_NASCIMENTO date not null,
DATA_ADMISSAO date not null,
DATA_DEMISSAO date,
REGIME_CONTRATACAO tinyint not null,
	
primary key(ID),
unique(MATRICULA)
		
) engine=InnoDB default charset=utf8;

Importante: É com extrema cautela que devemos criar um Script Flyway definindo o nome do banco de dados em create table. Isto é obrigatório pois se a execução do script ocorrer dentro de outro banco de dados, isto é, você esqueceu de selecionar o banco atual, a tabela será criada neste banco selecionado.
Muita atenção na criação de tabelas!

A coluna MATRICULA (neste caso) foi definida como única pois os funcionários não devem ter a mesma matrícula. Agora imagine a seguinte situação:

Matricula: 2012001, Nome: Alex Bittencourt
Matricula: 2012002, Nome: Alex Bittencourt

Neste caso precisamos que o campo NOME e MATRICULA sejem únicos.

A sintaxe do JAVA é diferente da SQL, isto é, para definir alguns campos devemos saber as sintaxes “equivalentes” entre si. Veja algumas sintaxes a seguir:

  • varchar = String
  • date = LocalDate
  • datetime = DateTime
  • tinyint = enum

Nota: Para o campo REGIME_CONTRATACAO (nossa enum Contrato) podemos utilizamos o tipo numérico tinyint e para datas, podemos utilizar date (aqui não obtemos a hora, diferente de datetime).

Como testar os Scripts Flyway?

Com o script flyway criado e revisado você pode utilizar o phpMyAdmin para testá-lo localmente em seu computador.

Lembre-se: Faça um BACKUP do seu Banco de Dados antes de realizar qualquer teste.

Adicionando tabela ao mini arquivo truncate

Após criar nosso script flyway é preciso adicionar a tabela referente a entidade Funcionario, no mini-arquivo-truncate, em nosso caso mini-projeto-truncate, para realizar um delete de todas as informações da tabela antes de inserir qualquer informação na mesma.

<dataset>

  <NOME_DO_BANCO.FUNCIONARIO />

</dataset>

Alteração de tabelas no flyway e inserção de index

Para alterar uma tabela, é criada uma tabela temporária que contenha as mesmas colunas da anterior, e a inserção de uma nova coluna caso seja esta a necessidade. Esta tabela temporária terá o mesmo nome da que se deseja alterar com a adição de um prefixo TMP, mas por que fazer isso? Deve-se adotar este procedimento pelo fato de muitas vezes a tabela a se alterar estar em produção, e se simplesmente fizer uma alteração, os dados da empresa serão perdidos. Um exemplo prático para esta situação seria vincular um funcionário a um departamento, considerando que a tabela DEPARTAMENTO já exista. Como realizar esta alteração? Será realizada da seguinte forma:

use  NOME_DO_BANCO;

drop table if exists TMP_FUNCIONARIO;
        
create table TMP_FUNCIONARIO (
        
ID integer not null auto_increment,
NOME varchar(60) not null,
MATRICULA varchar(60) not null,
DATA_NASCIMENTO date not null,
DATA_ADMISSAO date not null,
DATA_DEMISSAO date,
REGIME_CONTRATACAO tinyint not null,
DEPARTAMENTO_ID int,
        
primary key(ID),
unique(MATRICULA),      
index(DEPARTAMENTO_ID)      
) engine=InnoDB default charset=utf8;

insert into  TMP_FUNCIONARIO(
ID, NOME, MATRICULA, DATA_NASCIMENTO, DATA_ADMISSAO, DATA_DEMISSAO, REGIME_CONTRATACAO, DEPARTAMENTO_ID
)
select 
ID, NOME, MATRICULA, DATA_NASCIMENTO, DATA_ADMISSAO, DATA_DEMISSAO, REGIME_CONTRATACAO, DEPARTAMENTO_ID
from  FUNCIONARIO;
drop table if exists FUNCIONARIO;
rename table TMP_FUNCIONARIO to FUNCIONARIO;

O código acima criou uma tabela praticamente idêntica com tabela de produção, o que difere é a inserção da coluna DEPARTAMENTO_ID, o bloco do insert é responsável por informar quais colunas serão populadas com os dados da tabela que está em produção, e o select é o que de fato fará um backup dos dados para a tabela temporária. Com os dados migrados, a tabela antiga pode ser deletada, sem receio de impactos negativos com a operação, e por fim a tabela temporária é renomeada para o nome da tabela que estava em produção.

Houve a inserção de um index, mas o que vem a ser um Index ? E como ele funciona?

O index, funciona de forma análoga ao índice de um livro, que ao buscar um determinado assunto, já vai direto na página, na tabela o funcionamento é bem parecido, quando há inserção ou atualização de algum registro, a tabela sofre uma atualização e os indexes são armazenados em uma memória, quando se faz um Join, a busca já vai direto nesta memória, fazendo com que a busca tenha um melhor desempenho, sem o index seria necessário ler a tabela inteira todas as vezes que fosse buscar alguma informação. Os indexes geralmente são colocados no momento de criação da tabela, mas também podem ser colocados em uma eventual alteração.

Como se pode perceber a sintaxe de declaração de um index é bem parecida com a declaração de um unique.

Quais colunas devem ser colocadas como index? Geralmente os index são colocados em colunas que são acessadas com frequência, como por exemplo, uma chave estrangeira lógica, que apesar de não ter ligação explícita com a outra tabela, possui uma linha correspondente em outra tabela.

Obs.: Este procedimento deve ser adotado toda vez que se desejar alterar uma tabela criada, e não necessariamente a alteração deve ser feita para inserção de um index, de repente o nome de uma coluna foi escrito errado, ou se deseja alterar o tamanho dos campos.
O importante é não esquecer de colocar o prefixo TMP e realizar o procedimento de insert e select para cópia da tabela existente.

Tipos de dados comumente utilizados

Ao criar uma entidade é normal que se haja dúvida em qual tipo de dados será usado, ou qual o tamanho que se deve deixar reservado, para mitigar este tipo de dúvida este um padrão adotado na Objectos.

Confira o modelo a seguir:

Nome das colunas Tipo de dados Observação
Nome varchar(140) Para nomes de pessoas, adotar como tamanho padrão 140
DATAS EM GERAL date Usados quando se deseja armazenar somente dia/mês/ano (dd/mm/yyyy)
DATA_CRIACAO datetime Usado quando se deseja armazenar além da data, hora, minuto e segundo.
ID int/Integer No mySql int e Integer são tratados da mesma forma
Enum (Jdbc passa um ordinal) tinyint Para armazenar um valor numérico que pode variar de -128 a 127 ou de 0 a 255
Enum (Jdbc passa um getSqlValue) char(n) Para a definição da quantidade de caracteres verificar o tamanho máximo no enum, e principalmente, verificar se o que está sendo passado é um char.
Enum (Jdbc passa um getSqlValue) varchar(n) Para a definição da quantidade de caracteres verificar o tamanho máximo no enum, e principalmente, verificar se o que está sendo passado é uma string.
CPF varchar(20) Utilizar varchar no lugar de int, ou smallint
CEP varchar(8) Utilizar varchar no lugar de int, ou smallint
CNPJ varchar(40) Utilizar varchar no lugar de int
VALOR_FINANCEIRO double Utilizar double por conta da precisão ao tratar de dados com ponto flutuante.

Retornar aos Procedimentos! Voltar!

Leia mais uma vez! Revisar!


 
 

objectos, Fábrica de Software LTDA

  • R. Demóstenes, 627. cj 123
  • 04614-013 - Campo Belo
  • São Paulo - SP - Brasil
  • +55 11 5093-8640
  • +55 11 2359-8699
  • contato@objectos.com.br