terça-feira, 6 de novembro de 2012

O Problema da FK Inútil


Gostaria de esclarecer um comportamento não-intuitivo do Oracle (e de todos os SGBDs aderentes ao padrão ANSI/ISO SQL92), que pode levar a problemas de modelagem de dados e de consistência destes dados.

Imagine uma tabela XPTO, cuja PK é composta de dois campos: ID_XPTO e ID_EMPRESA. Agora imagine outra tabela ACME: (ID_ACME [PK], ID_XPTO [FK] e ID_EMPRESA [FK]). Em ACME, filha de XPTO, ID_XPTO e ID_EMPRESA estão ligados a XPTO por uma constraint do tipo FK, mas permitem valores NULL. Suponha que XPTO tem apenas um registro (1,100) e são inseridas em ACME as seguintes linhas:

1. ACME ( 1, 1, 100 );
2. ACME ( 2, 1, NULL );
3. ACME ( 3, NULL, 100 );
4. ACME ( 4, NULL, NULL );
5. ACME ( 5, 666, NULL );
6. ACME ( 6, NULL, 666 );

Quantas destas linhas serão aceitas ? TODAS ELAS. A presença do valor NULL desobriga o banco da validação da chave estrangeira, portanto devemos tomar o cuidado de adicionar uma constraint de check que garante que ou todos os valores da FK são nulos, ou nenhum é nulo:

ALTER TABLE ACME ADD CONSTRAINT CK_ACME_XXXX CHECK
  ((ID_XPTO IS NULL AND ID_EMPRESA IS NULL) OR (ID_XPTO IS NOT NULL AND ID_EMPRESA IS NOT NULL))

Atenção: Claro que a melhor opção seria deixar os campos em ACME como NOT NULL. A solução acima deve ser utilizada apenas se o requisito de negócio exigir que os campos permitam NULL.

Nenhum comentário:

Postar um comentário