Ismael Soares fez uma pesquisa sobre refatoração de banco de dados no programa Bluesoft Labs, essa é segunda parte de sua pesquisa, e é com muito orgulho que a Bluesoft compartilha com você, não deixe de conferir também os slides.
Antes de começar…
Qual a melhor estratégia?
- Avaliação do impacto: antes de fazer qualquer alteração na estrutura, deve-se avaliar o tamanho do impacto, tanto interno quanto externo, ou seja, descobrir todas as views, triggers, procedures, constraints e sistemas que serão afetados com a mudança.
- Definição do período de transição: após fazer a avaliação de impacto, será possível definir com mais precisão o período de transição. Entretanto, deve-se fazer um controle rigoroso para garantir que os prazos estabelecidos serão seguidos.
- Identificação de possíveis triggers circulares: em quase todas as refatorações que alteram a estrutura do modelo, é comum o uso de triggers para controlar o sincronismo dos dados. Se houver duas ou mais triggers, uma disparando contra a outra, e se não houver um controle rigoroso, elas irão entrar num loop infinito comprometendo o desempenho banco de dados.
- Criação e execução de testes: antes de alterar o modelo é preciso garantir que ele está atualmente funcionando. Crie testes automatizados para facilitar a identificação e correção dos impactos causados pelas refatorações.
- Executar a refatoração: crie os scripts necessários para aplicar a refatoração e adicione os comentários nas colunas, tabelas e triggers que serão removidas após o período de transição.
- Execute os testes: antes de anunciar as refatorações realizadas, é preciso garantir que nada parou de funcionar. Para isto, execute os testes criados antes da refatoração e caso algum deles falhe, faça as correções necessárias.
- Alteração das dependências internas e externas: se for possível, faça as alterações necessárias nos objetos internos (triggers, procedures, etc.) e externos (sistemas, outros bancos de dados, etc.) em paralelo. Caso contrário, prefira iniciar as alterações pelos objetos internos, já que estão mais próximos do seu domínio.
Estrutural
- Renomear colunas, tabelas, views, functions e procedures.
- Introduzir colunas calculadas.
- Introduzir surrogates key.
- Mesclar colunas e tabelas.
- Mesclar tabelas.
- Mover colunas, tabelas, views, functions e procedures.
- Dividir tabelas com muitas colunas.
- Substituir associações um-para-muitos (1-N) por tabelas associativas.
Exemplo
ALTER TABLE Customer ADD FirstName VARCHAR(40);
COMMENT ON Customer.FirstName 'Renaming of FName column, finaldate = November 14 2007';
COMMENT ON Customer.FName 'Renamed to FirstName,
dropdate = November 14 2007';
UPDATE Customer SET FirstName = FName;
CREATE OR REPLACE TRIGGER SynchronizeFirstName
BEFORE INSERT OR UPDATE
ON Customer
REFERENCING OLD AS OLD NEW AS NEW
FOR EACH ROW
DECLARE
BEGIN
IF INSERTING THEN
IF :NEW.FirstName IS NULL THEN
:NEW.FirstName := :NEW.FName;
END IF;
IF :NEW.Fname IS NULL THEN
:NEW.FName := :NEW.FirstName;
END IF;
END IF;
IF UPDATING THEN
IF NOT(:NEW.FirstName=:OLD.FirstName) THEN
:NEW.FName:=:NEW.FirstName;
END IF;
IF NOT(:NEW.FName=:OLD.FName) THEN
:NEW.FirstName:=:NEW.FName;
END IF;
END IF;
END;
/
On Nov 30 2007
DROP TRIGGER SynchronizeFirstName;
ALTER TABLE Customer DROP COLUMN FName;
Qualidade de dados
- Adicionar uma tabela de consulta.
- Aplicar códigos padrões.
- Aplicar tipos padrões.
- Adicionar ou remover chaves estrangeiras.
- Adicionar ou remover valores padrões em colunas.
- Mover dados de uma tabela para outra.
Considere a tabela “Address” que contém uma coluna chamada “State”. Nesta coluna são armazenadas as siglas dos estados com apenas dois caracteres. Neste modelo é possível apontar pelo menos dois problemas: o primeiro é a repetição desnecessária de dados, e a segunda é a falta de uma definição do significado de cada sigla.
Para resolver este problema pode-se adicionar uma tabela de consulta, também conhecida como Lookup Table ou Core Table. Nesta tabela, a coluna “State” vira chave primária, permitindo assim a criação de uma chave estrangeira na tabela “Address” para garantir a integridade. Além disto, deve ser adicionada uma nova coluna que irá qualificar o registro.
Outra vantagem com a aplicação desta refatoração é a possibilidade de fornecer aos sistemas externos uma lista de códigos nomeados para que não seja preciso usar enumeration.
CREATE TABLE State (
State CHAR(2) NOT NULL,
Name CHAR(50),
CONSTRAINT PKState
PRIMARY KEY (State)
);
ALTER TABLE Address ADD CONSTRAINT FK_Address_State
FOREIGN KEY (State) REFERENCES State;
INSERT INTO State (State)
SELECT DISTINCT UPPER(State) FROM Address;
UPDATE Address SET State = 'TX' WHERE UPPER(State) ='TX';
UPDATE State SET Name = 'Florida' WHERE State='FL';
UPDATE State SET Name = 'Illinois' WHERE State='IL';
UPDATE State SET Name = 'California' WHERE State='CA';
Integridade referencial
Considere as tabelas “Account” e “AccountStatus”. Elas estão interligadas através da coluna “StatusCode”. No entanto, não existe uma referência que restrinja este relacionamento, ou seja, podem ser inseridos registros na tabela “Account” mesmo sem existirem na tabela “AccountStatus”. Para resolver este problema, deve-se adicionar uma chave estrangeira na tabela ”Account” apontando para “AccountStatus”.
Existem dois tipos de chave estrangeira: a que a checagem é realizada no momento da inserção do registro, e a que faz a checagem apenas no final da transação (no commit). A primeira é a padrão da maioria dos bancos de dados, mas diminui o desempenho da transação. A segunda é uma boa opção quando os registros são inseridos e alterados na mesma transação e o que importa é apenas o resultado final, mas se não for usada com cautela pode desperdiçar processamento do banco de dados.
Script para criar a chave estrangeira com verificação imediata:
ALTER TABLE Account
ADD CONSTRAINT FK_Account_AccountStatus
FOREIGN KEY (StatusCode)
REFERENCES AccountStatus;
Script para criar a chave estrangeira com verificação no final da transação:
ALTER TABLE Account
ADD CONSTRAINT FK_Account_AccountStatus
FOREIGN KEY (StatusCode)
REFERENCES AccountStatus
INITIALLY DEFERRED;
Arquitetura
- Adicionar métodos CRUD (procedures para inserção, consulta, atualização e exclusão).
- Adicionar encapsulamento à tabela através de views.
- Adicionar métodos de cálculos.
- Adicionar tabelas apenas para leituras.
- Migrar métodos dos sistemas externos para o banco de dados.
Ao decidir usar métodos CRUD, leve em consideração os seguintes pontos:
- Quantidade de sistemas com acesso ao banco de dados.
- Regras de negócios que são repetidas em todos os sistemas e poderiam ser generalizadas no banco de dados.
- Necessidade de implementação de políticas de acesso aos dados.
- Familiarização da equipe de desenvolvimento com a linguagem usada pelo banco de dados.
CREATE OR REPLACE PACKAGE CustomerCRUD AS
TYPE customerType IS REF CURSOR RETURN
Customer%ROWTYPE;
PROCEDURE ReadCustomer
(readCustomerId IN NUMBER,customers OUT
customerType);
PROCEDURE CreateCustomer(....);
PROCEDURE UpdateCustomer(....);
PROCEDURE DeleteCustomer(....);
END CustomerCRUD;
/
CREATE OR REPLACE PACKAGE BODY CustomerCRUD AS
PROCEDURE ReadCustomer
(readCustomerId IN NUMBER,customerReturn OUT
customerType) IS
BEGIN
OPEN refCustomer FOR
SELECT * FROM Customer WHERE CustomerID =
readCustomerId;
END ReadCustomer;
END CustomerCRUD;
/
Conclusão
Os exemplos aqui apresentados mostram como é seguro e fácil evoluir um modelo de banco de dados utilizando a técnica de refatoração, e deixa claro também, que o gerenciamento destas mudanças é extremamente importante para o sucesso do projeto.
É provável que os desenvolvedores tenham um pouco de dificuldade no começo, caso nunca tenha tenham programado na linguagem do banco de dados, mas com um pouco de estudo e prática, será possível evoluir. Não veja estas dificuldades como uma barreira, mas sim como uma oportunidade para dividir o conhecimento, que às vezes, está concentrado apenas nos profissionais de banco de dados.
Referências
- Ambler, Scott W., Pramod J. Sadalage (2006). Refactoring Databases: Evolutionary Databases Design. New York: Addison Wesley Professional.
- Ambler, Scott W., Pramod J. Sadalage (2006). Refactoring Databases: The Process.
1 Comentário
Bom!! Parabéns!!