Oracle: Constraints NOVALIDATE

Fala aí galera, tudo certo?

Passando hoje para registrar um dica que recebi do Bruno Proença, sobre constraints novalidade do Oracle.

Constraints NOVALIDATE

No projeto que trabalho, sofremos um pouco com modelagem de dados. Quando o projeto foi concebido, uma das premissas era receber dados do sistema origem do cliente de qualquer jeito, assim se mesmo estivesse com problema de integridade ou duplicidade, criticamos o registro.

Desta forma, podemos chamar nosso modelo de dados de “fraco”, já que praticamente não temos constraints.

Como alguns dos problema de performance que enfrentamos hoje diz respeito a modelagem de dados, o Bruno estudou uma forma de tentamos resolver este problema, foi aí que ele encontrou as constraints novalidate.

A ideia por traz desta solução é criar as constraints para as tabelas necessárias e não se importar com o dados legados, ou seja, apenas os dados novos que entrarem na tabela estarão sujeitos à validação de constraints. O Oracle passa a não verifica os dados antigos para saber se algo viola esta nova restrição.

Esta abortagem, não resolve todo o problema, mas faz com que o problema não aumente, e isso é muito bom para nosso projeto.

Exemplo de uso:

Vamos criar uma tabela para teste apenas com a constraint de PK definida:

CREATE TABLE TB_TESTE (
ID NUMBER NOT NULL,
CODIGO VARCHAR2(20),
DESCRICAO VARCHAR2(20),
CONSTRAINT TB_TESTE_PK PRIMARY KEY ( ID ) ENABLE
) ;

Agora fazemos os seguintes inserts:

INSERT INTO TB_TESTE VALUES (1, 'COD-X', 'AAAAAA');
INSERT INTO TB_TESTE VALUES (2, 'COD-X', 'BBBBBB'); -- DUPLICOU CODIGO
INSERT INTO TB_TESTE VALUES (3, 'COD-Y', 'CCCCCC');

Se tentamos criar um constrains convencional um erro será lançado pelo Oracle:

ALTER TABLE TB_TESTE
ADD CONSTRAINT TB_TESTE_UK1 UNIQUE (CODIGO) USING INDEX;
--ERRO: ORA-02299: cannot validate (TB_TESTE_UK1) - duplicate keys found

O Oracle reclama que a chave definida possui duplicidade.

Agora vamos criar a constraint novalidade. Mais antes, é importante lembrar, que todas as vezes que criamos uma constraint de UK, como fizemos a cima, o Oracle cria também um índice (UNIQUE) com o mesmo nome e colunas da constraint. É por este motivo que recebemos o erro ORA-02299.

Para contornar este problema, temos que criar antes um índice não único (NONUNIQUE) antes da constraint, da seguinte forma:

CREATE INDEX TB_TESTE_UK1 ON TB_TESTE(CODIGO) TABLESPACE TBS_INDICES;

Em seguida a constraint:

ALTER TABLE TB_TESTE
ADD CONSTRAINT TB_TESTE_UK1 UNIQUE (CODIGO)
USING INDEX ENABLE NOVALIDATE ;

Pronto, nenhum erro será lançado agora. Mas se tentar incluir registros com código duplicado, olha o que acontece:

INSERT INTO TB_TESTE VALUES (4, 'COD-Z', 'DDDDDD');
-- OK: 1 row inserted.
INSERT INTO TB_TESTE VALUES (5, 'COD-Z', 'EEEEEE');
-- ERRO: ORA-00001: unique constraint (TB_TESTE_UK1) violated

É isso aí galera, usando este abordagem, o Oracle só irá validar os novos registros, ou os registros antigos se estão alterados após a criação na constraint novalidade.

Isso também funciona para as FKs!

Espero que tenham gostado.

Fonte: NOVALIDATE Constraints – No really

um comentário

  1. […] Oracle: Constraints Novalidate […]

    Curtir

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair /  Alterar )

Foto do Google

Você está comentando utilizando sua conta Google. Sair /  Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair /  Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair /  Alterar )

Conectando a %s

%d blogueiros gostam disto: