Introdução
De nada adianta termos imensos bancos de dados armazenando incontáveis bytes de dados, que são constantemente inseridos, modificados, eliminados, se não podemos transformá-los em informação. E, de preferência, informação útil. E sem garantir que nossos dados armazenados estão íntegros, dificilmente conseguimos transformar esses bytes em informação real. Não importa quão avançada sejam suas ferramentas ou técnicas de aplicação em seu ambiente, nada irá adiantar se não houver um investimento na qualidade de seus dados.
Ao falarmos de integridade de dados, podemos citar alguns exemplos que podem e ajudam a garanti-la:
· Firewalls
· Sistema Gerenciador de Banco de Dados (SGDB)
· Revisão regular de privilegio aos dados
· Encriptação
· Controle na prevenção de corrupção de dados
· Compliance
· Fácil recuperação de dados e performance
· Integração com os sistemas de armazenamento (discos, fitas)
· Trafego dos dados pela rede
· E mais...
Usando os exemplos citados acima, podemos dividir a integridade dos dados em 2 grupos:
· Sob a ótica do sistema: Integração com o hardware como discos, fitas; conexão de rede; firewalls; integração entre o SGDB e o sistema.
· Sob a ótica da aplicação: Integridade referencial; triggers; lockings; controle de acesso aos dados.
Nesse artigo será abordado a ótica da aplicação, mais precisamente da parte que depende do Sistema Gerenciador de Banco de Dados (SGDB) de integridade referencial, integridade semântica, integridade de domínio. Cada um desses itens será explicado no decorrer do texto.
O Sistema Gerenciador de Banco de Dados e a integridade dos dados
Os SQL statements INSERT, DELETE e UPDATE modificam os dados em um banco de dados existentes. Toda vez que os dados são alterados existe a possibilidade que integridade lógica ser afetada. Por exemplo, a inserção de um produto inexistente em um pedido um cliente, ou um cliente pode ser eliminado mesmo tenho ainda pedidos pendentes em seu nome. Em ambos os casos houve perda da integridade dos dados.
A integridade de dados em SGDBs é uma combinação de:
· Integridade semântica: o dado de uma coluna sempre será do tipo de dado definido na criação da coluna
· Integridade de entidade: cada linha de uma tabela possui um indicador que garanta a unicidade da mesma.
· Integridade referencial: os relacionamentos lógicos entre as entidades serão forçados pelos SGDB
· Integridade de domínio: Domínio é um conjunto de valores previamente definido no qual uma coluna só poderá conter valores pertencentes a esse domínio.
Quando bem definido um banco de dados, provavelmente esse quatro conceitos de integridade serão aplicados.
Integridade Semântica
Constraints
· Constraint NOT NULL (não nulo)
· Constraint única
· Constraint de validação (check constraint)
Segue abaixo um resumo sobre esses tipos de constraints.
Constraint de dados
Esse tipo de constraint pode ser considerado o mais simples e por muitas vezes ignorado como um constraint. Ele é o que delimita o tipo de dado de cada coluna em uma tabela. Os tipos de dados disponíveis na maioria dos SGDBs existentes pode ser dividia em:
· Alfa numérico ou caracteres
· Data e tempo
· Grandes objetos
Tipos de dados numéricos mais comuns:
Tipo de Dados | Descrição |
SMALLINT | Números inteiros pequenos |
INTEGER | Números inteiros |
DECIMAL | Números decimais. Contem a parte inteira e a decimal (13,2 por exemplo) |
| O número floating-point de precisão simples é um floating-point de 32 bit |
FLOAT | O número floating-point de precisão dupla é um floating-point de 64 bit |
Tipos de dados alfa-numérico ou caracteres:
Tipo de Dados | Descrição |
| Para cadeias fixas de caracteres alfa numéricos |
VARCHAR | Para cadeias variáveis de caracteres alfa numéricos |
Tipos de dados data e tempo:
Tipo de Dados | Descrição |
DATE | Data com valores representando dia, mês e ano |
TIME | Tempo com valores representando hora, minuto e segundo |
TIMESTAMP | Data e Tempo juntos com valores que representam ano, mês, dia, hora, minuto, segundo e milisegundo |
Observação: na perspectiva do usuário, os tipos de dados data e tempo parecem ser do tipo alfa-numérico, porém fisicamente são armazenados como do tipo binário compactado.
Tipos de dados grandes objetos, tais como LOB (large object), armazenam grande quantidade de bytes podem ser utilizados para armazenar objetos do tipo imagem ou som.
Podemos considerar que a chave primaria (primary key), que será explicada mais adiante, é um tipo de constraint única. Lembrando que uma tabela pode ter apenas uma chave primária, porém diversas constraint únicas.
Constraint de validação (check constraint)
A constraint de validação determina um conjunto de valores permitidos para uma determinada coluna na tabela. Essas constraints são definidas explicitamente no DDL (data definition language) de uma tabela com expressões Booleanas similares a clausula WHERE do SQL. Constraint de validação é forçada em qualquer inserção ou atualização da coluna. Caso a inserção ou atualização da coluna não esteja de acordo com a definição da constraint, a mesma não será executada.
Por exemplo, vamos supor que a tabela FUNCIONARIO possua uma coluna SALARIO e que o valor do salário de cada funcionário não possa ser maior que 50.000,00, é possível criar uma constraint para essa regra:
CREATE TABLE FUNCIONARIO (
NUMERO_FUNCIONARIO SMALLINT NOT NULL,
SALARIO DECIMAL (9,2) NOT NULL CHECK SALARIO >= 50.000);
Constraint de validação pode ser muito útil para garantir regras de negócio, pois ela não pode ser sobreposta. Uma vez definida é dada a garantia que a regra será respeitada.
Utilizando esse tipo de integridade torna as suas aplicações mais robustas, consistentes e simples, pois não é necessário controlar as regras dentro do próprio código de programação ou utilizando uma subrotina. Dessa maneira é isolada em apenas um lugar a regra de negócio. Havendo a necessidade de mudar alguma regra de negócio, basta apenas mudar a constraint de validação na tabela ao invés de sair alterando códigos e mais códigos de programação uma vez que a mesma regra pode estar replicada em diversos pontos da sua aplicação.
Integridade Referencial
Em resumo, integridade referencial é um conceito de banco de dados que garante que todos os relacionamentos propostos entre tabelas no modelo de entidade-relacionamento (ER) serão respeitados dando a certeza que os dados de um banco de dados estarão íntegros. Esses relacionamentos são baseados nas definições de uma chave primária e uma chave estrangeira e regras pré-definidas para a manipulação dessas chaves.
Vale lembrar que existem diversos livros, manuais, tratados que falam sobre integridade referencial, sendo assim esse artigo apenas deseja explicar de uma maneira simples e com exemplos esse conceitos.
Conceitos de IR (Integridade Referencial)
A figura abaixo mostra alguns conceitos de IR e o uso de sua terminologia:Chave Candidata
Na Figura 1 as chaves candidatas da tabela FUNCIONARIO o NR_
Chave Única
Uma chave única que definida pela constraint única que garante que um atributo ou um conjunto de atributos não pode ser duplicado na mesma tabela.
A chave primária de uma tabela é uma das chaves candidatas que melhor identifica uma tabela. Os critérios para escolher a chave primária são:
· O conteúdo da coluna ou do conjunto de colunas deve sempre existir, em outras palavras deve possuir a constraint semântica NOT NULL.
· O valor da chave não deve poder ser alterado.
A chave primária tem as seguintes características:
· Apenas uma chave primária por tabela
· Pode ser composta por mais de uma coluna
· Obrigatoriamente ser NOT NULL (não nulo)
No exemplo mostrado na Figura 1 a coluna NR_
Na mesma figura, a chave primaria da tabela DEPARTAMENTO é NR_DEPT (número do departamento).
Chave Estrangeira
· Pode ser composta de uma ou mais colunas contando que ela seja exatamente igual à chave primaria que ela é relacionada (tipo de dado e tamanho)
· Pode conter a clausula NULL
Chave Parente
Tabela parente
Tabela Independente
Uma tabela que não possui chave estrangeira é chamada de tabela independente.
Linha Dependente
Integridade de entidade
Constraint Referencial
Regras e opções de IR
O modelo relacional possui um conjunto de regras para controle da inserção, atualização e eliminação dos dados nas tabelas. As regras são:
· Regra de Inserção (INSERT)
· Regra de Atualização (UPDATE)
· Regra de Eliminação (DELETE)
Regra de Inserção
A regra de inserção é uma regra implícita, diferentemente das regras de atualização e eliminação que precisam ser declaradas no momento de criação das chaves estrangeiras.
· Exatamente o mesmo valor da chave parente da respectiva tabela parente.
Regra de Atualização
A regra de atualização deve ser explicitamente definida no momento de criação da chave estrangeira. Essa regra é acionada quando:
· A chave estrangeira da tabela dependente é atualizada. Nesse caso, assim como a regra de inserção, o valor só pode ser alterado para nulo, caso seja permitido, ou para um valor existente na chave parente da tabela parente.
· A chave primária da tabela parente é atualizada
Existem três opções para a regra de atualização:
· RESTRITO:
o A chave parente não pode ser atualizada caso exista alguma chave estrangeira em qualquer tabela dependente que o possua o mesmo valor.
· CASCATA:
o Caso a chave parente seja atualizada, todas as chaves estrangeiras respectivas de cada tabela dependente que contenha o valor da chave parente serão também atualizadas para o novo valor.
· NULO:
o Caso a chave parente seja atualizada, todas as chaves estrangeiras respectivas de cada tabela dependente que contenha o valor da chave parente serão atualizadas com o NULO.
Cada chave estrangeira é associada a sua regra de atualização respectiva. A regra de atualização determina se a atualização pode ser feita ou não. Sendo assim, uma chave parente não poderá ser atualizada caso qualquer chave estrangeira respectiva for definida com a regra RESTRITO.
Do mesmo modo que a regra de atualização, a regra de eliminação deve ser definida no momento da criação da chave estrangeira. Essa regra é imposta toda vez que houver tentativa de eliminar uma linha da tabela parente.
· RESTRITO:
o A linha da tabela parente não pode ser eliminada caso exista na tabela dependente o mesmo valor na chave parente e de sua respectiva chave estrangeira.
· CASCATA:
o Todas as linhas de qualquer tabela dependente que possua o valor na chave estrangeira igual ao valor da chave parente também serão eliminadas.
o A eliminação é propagada para os dependentes das tabelas dependentes
o Se uma das eliminações falharem o processo inteiro falha também
· NULO
o Todas as linhas de qualquer tabela dependente que possua o valor na chave estrangeira igual ao valor da chave parente serão atualizadas para o valor NULO
· Quando possua a regra CASCATA e no momento da propagação da eliminação encontre alguma chave estrangeira que esteja definida como RESTRITO nas tabelas dependentes da tabela dependente.
A figura 2 mostra exemplo de um modelo de entidade-relacionamento com suas respectivas regras de eliminação:
Conclusão
No mundo atual, aonde a informação vem se tornando cada vez valiosa, de nada adianta termos imensos bancos de dados contendo milhares de dados sem garantimos a integridade desses dados. A Integridade Referencial é um conceito que existe desde os primórdios do banco de dados e hoje entra como um papel fundamental para a garantia da veracidade das informações armazenadas.
Praticamente todos os Sistemas Gerenciadores de Banco de Dados (SGDB) possuem mecanismos para a implementação da IR facilitando o trabalho de programadores e analistas, pois, uma vez implementada existe a garantia que o SGDB irá gerenciá-la com todas essas regras em um único lugar encapsuladas.