Fala galera, bom dia.
Tudo bem?
Estou um pouco ausente neste mês devido as correrias da minha vida profissional e acadêmica, mas sempre que possível compartilhando com vocês um pouco do meu conhecimento e experiência.
O post de hoje poderia ser diferente dos outros, na sessão Dica do Mês vou apresentar um pouco mais sobre os conceitos básicos de banco de dados voltados para área de modelagem, estou me referindo as chamadas Restrições de Integridade (RI), algo bastante útil e importante quando estamos realizando as definições da estrutura lógica para armazenamento de dados em qualquer banco de dados. Então vamos começar a falar um pouco mais sobre este conceito também criado na década dos anos 70 por Edgar Frank Codd.
Falando um pouco sobre integridade…
A integridade de dados é uma das características essenciais da segurança da informação, e garante que as informações não sofreram alterações que não foram autorizadas ou que são impróprias. Utilizada para assegurar que um documento não é alterado depois de ter sido assinado.
Quando vamos projetar um banco de dados, imaginamos as possíveis formas para que nossa aplicação grave os dados corretamente no banco de dados, mas as vezes, esquecemos de definir, a nível de banco, quais as validações que devem ser feitas para evitar inconsistências nos dados e que, futuramente, se tornariam dores de cabeça.
No contexto de bancos de dados relacional é comum falar de integridade referencial, que tem como objetivo conservar as relações existentes entre tabelas quando algumas linhas são inseridas ou eliminadas.
Restrições de Integridade….
As chamadas RIs possuem o objetivo de garantir a exatidão e a consistência dos dados em uma Banco de dados relacional. Ou seja, garantir que dados representem assertivamente a realidade modelada. A integridade dos dados é tratada nas bases de dados através do conceito de integridade relacional e é garantida pelo próprio SGDB.
Existem vários tipos de restrições de integridade. Codd, inicialmente definiu 2 tipos de restrições, mas na sua segunda versão do modelo relacional ele definiu 5 tipos de restrições de integridade.
Mas antes de conhecer este tipos, vamos entender um pouco o conceito de domínio dos atributos: O domínio indica os possíveis valores de um atributo. A integridade de domínio verifica se os dados são do tipo permitido (alfanumerico, numerico,etc), tamanho do campo, se ele pode ser nulo ou não. Por exemplo, é possível definir que um atributo “idade” de um funcionário é sempre um valor inteiro positivo.
Os cinco tipos de restrições…
Restrição de Chave: Impede que uma chave primária se repita. Um campo chave primária diferencia de forma única os registros (linhas) de uma relação (tabela).
Restrição de Domínio: Impede que uma chave primária receba como valor NULL (nulo).
Integridade de vazio: Verifica se um campo pode ou não receber valor NULL. Sub-item da integridade de domínio.
Integridade referencial: Uma chave estrangeira de uma relação tem que coincidir com uma chave primária da sua tabela “pai” a que a chave estrangeira se refere. Ou seja, não só deve existir o atributo (campo), como também, o valor referenciado.
Integridade definida pelo usuário: Permite definir regras comerciais que não se encaixam em outras categorias de integridade.
Elementos que formam as Restrições de Integridade…
Integridade Semântica: Garante que o dado inserido em uma linha da tabela seja um valor válido. Para esse valor ser válido deve ser do mesmo tipo de dados definido na especificação da coluna na tabela.
Imagine o atributo de uma determinada entidade definido como DATA, por padrão este atributo deverá conter somente dados relativos a DATA. É justamente esta definição que nos permite ter a certeza que no campo DATA_CONTRATACAO só terá datas válidas.
Caso um SGDB permita a inserção de um outro tipo de dado diferente do definido, a integridade semântica será violada. A integridade semântica em um SGDB é aplicada com a utilização de constraints.
Constraints: Pode ser definido resumidamente como uma regra que limita o valor que pode ser inserido, modificado ou eliminado em uma tabela. Na linguagem SQL temos os seguintes tipos de constraints:
- Constraint de dados;
- Constraint NOT NULL (não nulo);
- Constraint única; e
- Constraint de validação (check constraint).
Constraints 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 informações disponíveis na maioria dos SGDBs existentes pode ser dividia em:
- Numérico;
- Alfanumérico ou caracteres;
- Data e tempo; e
- Grandes objetos.
Constraints Not Null: O conceito de nulo é utilizado quando uma determinada coluna ou atributo de uma linha na tabela não possui valor ou este valor é desconhecido. Por outro lado, existem colunas / atributo que obrigatoriamente precisam de valor informado.
Por exemplo, em uma tabela chamada FUNCIONARIO, onde estão dados de funcionários, o atributo NUMERO_FUNCIONARIO é obrigatório. Nesse caso é possível utilizar a constraint NOT NULL para garantir que haverá informação nessa coluna.
Importante frisar que NULO é diferente de brancos e zeros. Temos que lembrar também que tanto branco quanto zero são valores válidos e que são levados em conta em funções de coluna, tais como média, somatório, máximo, mínimo. Sendo que o NULO é desconsiderado nessas funções.
Constraints Única (Unique): Reconhecida e tratata como uma regra única que garante e não permite a existência de valores duplicados da mesma coluna ou em um conjunto de colunas na mesma tabela.
Usando o mesmo exemplo da tabela FUNCIONARIO, podemos utilizar uma constraint única na coluna NUMERO_FUNCIONARIO para garantir que dois ou mais funcionários possuam o mesmo número de identificação.
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.
Constraints de Validação (Check): Esta constraint determina um conjunto de valores permitidos para uma determinada coluna na tabela. Através deste tipo de constraints podemos definir de forma explícita através da linguagem DDL (Data Definition Language) de uma tabela com expressões Booleanas similares a clausula WHERE da linguagem Transact-SQL.
Uma 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 erra regra:
CREATE TABLE FUNCIONARIO
(NUMERO_FUNCIONARIO SMALLINT NOT NULL,
SALARIO DECIMAL (9,2) NOT NULL CHECK SALARIO >= 50.000);
Observações: Uma 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.
Utilizar 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; e
Havendo a necessidade de mudar alguma regra de negócio, basta apenas alterar 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.
Realizando uma prática…
Após conhecermos um pouco sobre o conceito e elementos que formam as restrições de integridade, vamos então colocar “a mão na massa” ou melhor como eu sempre digo no teclado e construir um simples exemplo de como podemos fazer uso de forma mais coerente e organizada do uso da restrição de integridade em nossas tabelas. Para tal utilizaremos o Bloco de Código 1 apresentado abaixo:
— Bloco de Código 1 — Aplicando o conceito de restrições de integridade —
— Criando o Banco de Dados —
Create Database RI
Go
— Acessando o Banco de Dados —
Use RI
Go
— Criando a Tabela Funcionarios utilizando Constrainst – Not Null, Null, Check, Default e Unique —
Create Table Funcionarios
(Codigo Int Primary Key Identity(1,1),
Nome Varchar(80) Not Null,
Sexo Char(1) Check (Sexo = ‘F’ or Sexo = ‘M’),
RG Int Not Null Unique NonClustered,
CPF Int Not Null Unique NonClustered,
DataNascimento Date Check (DataNascimento >= ‘1950-01-01’),
DataCadastro DateTime Default GetDate(),
Email Varchar(100) Null)
Go
— Criando a Tabela Clientes utilizando Constrainst – Not Null, Null, Check, Default e Unique —
Create Table Clientes
(Codigo Int Identity(1,1),
Nome Varchar(80) Not Null,
Sexo Char(1),
RG Int Not Null,
CPF Int Not Null,
DataNascimento Date,
DataCadastro DateTime Constraint DF_Clientes_DataCadastro Default GetDate(),
Email Varchar(100) Null
Constraint PK_Clientes_Codigo Primary Key (Codigo),
Constraint CK_Clientes_Sexo Check (Sexo = ‘F’ or Sexo = ‘M’),
Constraint UQ_Clientes_RG Unique NonClustered (RG),
Constraint UQ_Clientes_CPF Unique NonClustered (CPF),
Constraint CK_Clientes_DataNascimento Check (DataNascimento >= ‘1950-01-01’))
Go
— Adicionando uma nova Constraint —
Alter Table Clientes
Add Constraint DF_Clientes_Sexo Default ‘M’ for Sexo
Go
— Removendo uma Constraint já existente —
Alter Table Clientes
Drop Constraint CK_Clientes_DataNascimento
Go
— Adicionando uma nova Constraint do tipo Check —
Alter Table Clientes
Add Constraint CK_Clientes_DataNascimento
Check(DataNascimento >=’1900-01-01′)
Go
Perfeito, após executarmos este bloco de código temos nosso ambiente totalmente criado seguindo as definições de restrições de integridade que aplicamos no script.
Você pode estar se perguntando mas o que existe de diferença entre criar uma tabela sem definir o nome dados constraints em comparação com uma tabela que possui o nome das constraints definidas. A resposta para esta sua dúvida será respondida através da Figura 1 apresentada abaixo:
Figura 1 – Restrições de integridade criadas em cada tabela.
Analisando a Figura 1 podemos notar claramente a diferença, quando definimos um nome para nossas constrainst o Microsoft SQL Server atribui exatamente o nome de definimos no momento da crição da tabela, com isso, teremos mais facilidade para realizar uma manutenção nestes objetos, bem como, toda documentação e apresentação da estrutura do nosso banco de dados será mais limpa e organizada.
Sendo assim chegamos ao final de mais uma dica do mês.
O conhecimento técnico é muito importante para qualquer profissional, mas não podemos deixar de lado o conhecimento acadêmico adquirido ao longo dos anos dentro das instituições de ensino.
Este é um ponto fundamental, valorizar e conhecer a diferença entre um bom profissional e o profissional reconhecido e respeitado no mercado de trabalho, está justamente ligado na capacidade do mesmo em saber aliar o conhecimento teórico com o conhecimento prático, como muitos costumam dizer aliar a téoria a prática, sendo este o objetivo deste post.
Espero que você tenha gostado, que as informações e exemplos publicadas possam de alguma maneira ajudar e colaborar com suas atividades diárias, profissionais e ou acadêmicas.
Desejo um forte abraço, agradeço mais uma vez a sua visita.
Até mais.