Páginas

22 de set. de 2010

DEFERRABLE CONSTRAINTS para otimizar cargas de dados

     
     Um recurso muito interessante, mas pouco utilizado em constraints, é o de constraints postergáveis (adiáveis) ou DEFERRABLE CONSTRAINTS.
   
     Por padrão, CONSTRAINTS são validadas (aplicadas e verificadas) no momento em que uma instrução DML (INSERT, UPDATE ou DELETE) é executada no Banco de Dados. No caso de uma instrução INSERT, por exemplo, no momento em que ela é executada, se um valor fornecido para uma coluna que tenha uma CONSTRAINT for um valor que viole a regra ou condição imposta pela CONSTRAINT, a instrução irá retornar um erro. Deste modo, sempre que uma instrução violar uma CONSTRAINT ela irá gerar um erro "imediatamente", ou seja, a instrução será validada sempre no momento de sua execução.
   
    É possível postergar ou adiar a validação da CONSTRAINT para o momento do término da transação em que uma instrução está contida. Em outras palavras, quando temos DEFERRABLE CONSTRAINTS, a validação da CONSTRAINT só ocorre no momento em que a transação finalizar (após um COMMIT ou ROLLBACK). Uma transação poderá conter múltiplas instruções. Não importa quantas instruções ela tenha, se a CONSTRAINT for postergável, ela será validada somente no término da transação.
   
    DEFERRABLE CONSTRAINTS são úteis em casos tais como:
         
          1- Na atualização de 2 tabelas que possuem relacionamento, onde precisamos incluir uma linha nova, primeiro na tabela que contém a chave-estrangeira (tabela filha) e depois na tabela que contém a chave-primária do relacionamento (tabela mãe).
       
            Ex.: INSERT INTO EMPREGADO (ID, NOME, DEPARTAMENTO_ID) VALUES (103, 'FÁBIO PRADO', 23);
                 INSERT INTO DEPARTAMENTO (DEPARTAMENTO_ID, NOME) VALUES (23, 'TI');
                 COMMIT;
  
    
            Obs.: Neste caso, considerando que existe uma DEFERRABLE CONSTRAINT de chave-estrangeira na coluna DEPARTAMENTO_ID da tabela EMPREGADO referenciando a coluna ID na tabela DEPARTAMENTO, a transação contendo as 2 instruções INSERT seria executada com sucesso. Se a CONSTRAINT fosse criada no modo padrão (imediato), ao executar a primeira instrução INSERT (na tabela EMPREGADO) um erro ocorreria.
               
          2- Na inserção de dados em massa. Ao submeter comandos para inserir, por exemplo, milhares de linhas em uma tabela, o processo de inserção ocorre mais rápido se a checagem das constraints for executada somente no final, de uma única vez.
          
    Ao criar uma CONSTRAINT do tipo DEFERRABLE é possível definir que a postergação da validação esteja inicialmente desabilitada, ou seja, ela será validada imediatamente, no momento da execução de uma instrução (não no final da transação).    
        Ex.:
      CREATE TABLE EMPREGADO (            ID NUMBER,
            NOME VARCHAR2(30),
            DEPARTAMENTO_ID NUMBER,
            CONSTRAINT EMP_PK PRIMARY KEY (ID),
            CONSTRAINT EMP_DEPTO_FK FOREIGN KEY (DEPARTAMENTO_ID)
              REFERENCES DEPARTAMENTO (DEPARTAMENTO_ID)
              DEFERRABLE INITIALLY IMMEDIATE);


    ou é possível definir que ela esteja inicialmente habilitada, ou seja, que ela será validada somente no término da transação:
   
      CREATE TABLE EMPREGADO (            ID NUMBER,            NOME VARCHAR2(30),            DEPARTAMENTO_ID NUMBER,             CONSTRAINT EMP_PK PRIMARY KEY (ID),            CONSTRAINT EMP_DEPTO_FK FOREIGN KEY (DEPARTAMENTO_ID)             REFERENCES DEPARTAMENTO (DEPARTAMENTO_ID)            DEFERRABLE INITIALLY DEFERRED);

    A qualquer momento é possível alterar o "comportamento" DEFERRABLE da CONSTRAINT:

            a) Se for desejado alterar para validar imediatamente (sem postergação):
                    SET CONSTRAINTS EMP_DEPTO_FK IMMEDIATE;           
             
            b) Se for desejado alterar para validar somente no final da transação (com postergação):
                    SET CONSTRAINTS EMP_DEPTO_FK DEFERRED;
  



Bom pessoal, por hoje é só!

[]s

16 comentários:

  1. Colega, obrigado pelo post, estou estudando para concurso e tinha uma questão com esse comando e nunca tinha puvido falar.
    abs

    ResponderExcluir
    Respostas
    1. Legal, em qual concurso caiu questão sobre este assunto?

      Excluir
  2. Excelente post. Claro e objetivo! parabéns!!

    ResponderExcluir
  3. Explicação direta. Simples e eficiente!!

    ResponderExcluir
  4. Fábio, sua didática impressiona pela simplicidade e eficiência. Parabéns!

    ResponderExcluir
  5. Explicação extremamente clara.
    Valeu!

    ResponderExcluir
  6. Cara, post sucinto e muuuuiito útil.
    Me auxiliou a contornar processo de carga entre ambientes.
    Parabéns.

    ResponderExcluir
  7. excelente blog, vai me ajudar em meus serviços de SEO obrigada, valeu mesmo pelo conteudo, parabéns aos envolvidos!

    ResponderExcluir