Definição
O que é um Banco de Dados Relacional?
Um banco de dados relacional é um tipo de banco de dados que organiza os dados em tabelas (também chamadas de relações), onde cada tabela é composta por linhas (registros/tuplas) e colunas (atributos/campos).
O modelo relacional foi proposto por Edgar F. Codd em 1970, e é baseado na teoria matemática dos conjuntos e na álgebra relacional. A Oracle Corporation foi uma das primeiras empresas a implementar comercialmente este modelo, lançando o Oracle Database em 1979.
Características Principais:
- Dados organizados em tabelas: Estrutura bidimensional clara e intuitiva
- Relacionamentos entre tabelas: Conexões lógicas através de chaves
- Integridade referencial: Garante consistência dos dados relacionados
- Linguagem SQL: Interface padrão para manipulação dos dados
- ACID: Atomicidade, Consistência, Isolamento e Durabilidade das transações
Estrutura de uma Tabela
| ID_FUNCIONARIO (PK) | NOME | DEPARTAMENTO_ID (FK) | SALARIO |
|---|---|---|---|
| 1 | João Silva | 10 | 5000.00 |
| 2 | Maria Santos | 20 | 6500.00 |
| 3 | Pedro Costa | 10 | 4500.00 |
Linha (Registro/Tupla)
Cada linha representa uma instância única de uma entidade. No exemplo, cada linha é um funcionário diferente.
Coluna (Atributo/Campo)
Cada coluna representa uma característica da entidade. Ex: NOME, SALARIO são atributos do funcionário.
Chaves: O Coração do Modelo Relacional
Chave Primária (Primary Key - PK)
Identifica unicamente cada registro na tabela. Não pode ser nula e deve ser única.
- Pode ser uma coluna única (simples) ou múltiplas colunas (composta)
- Oracle cria automaticamente um índice único para a PK
- Exemplo: ID_FUNCIONARIO na tabela FUNCIONARIOS
Chave Estrangeira (Foreign Key - FK)
Cria relacionamentos entre tabelas, referenciando a chave primária de outra tabela.
- Garante integridade referencial (não permite referências inválidas)
- Pode ser nula (relacionamento opcional)
- Exemplo: DEPARTAMENTO_ID em FUNCIONARIOS referencia ID em DEPARTAMENTOS
Chave Única (Unique Key - UK)
Garante que os valores de uma coluna (ou conjunto) sejam únicos, mas permite NULL.
- Uma tabela pode ter múltiplas chaves únicas
- Exemplo: EMAIL ou CPF em uma tabela de clientes
Aplicação Prática
Criando Tabelas com Chaves no Oracle
Vamos criar um esquema simples de RH com as tabelas DEPARTAMENTOS e FUNCIONARIOS, demonstrando o uso de chaves primárias e estrangeiras:
-- Criando a tabela DEPARTAMENTOS
CREATE TABLE departamentos (
id_departamento NUMBER(10) PRIMARY KEY,
nome VARCHAR2(100) NOT NULL,
localizacao VARCHAR2(100),
orcamento NUMBER(15,2)
);
-- Criando a tabela FUNCIONARIOS com FK para DEPARTAMENTOS
CREATE TABLE funcionarios (
id_funcionario NUMBER(10) PRIMARY KEY,
nome VARCHAR2(100) NOT NULL,
email VARCHAR2(100) UNIQUE,
data_admissao DATE DEFAULT SYSDATE,
salario NUMBER(10,2) CHECK (salario > 0),
departamento_id NUMBER(10) REFERENCES departamentos(id_departamento)
);
-- Inserindo departamentos
INSERT INTO departamentos VALUES (10, 'Tecnologia', 'São Paulo', 500000);
INSERT INTO departamentos VALUES (20, 'Recursos Humanos', 'Rio de Janeiro', 200000);
INSERT INTO departamentos VALUES (30, 'Financeiro', 'São Paulo', 300000);
-- Inserindo funcionários
INSERT INTO funcionarios VALUES (1, 'João Silva', 'joao@empresa.com', DATE '2020-03-15', 5000, 10);
INSERT INTO funcionarios VALUES (2, 'Maria Santos', 'maria@empresa.com', DATE '2019-07-01', 6500, 20);
INSERT INTO funcionarios VALUES (3, 'Pedro Costa', 'pedro@empresa.com', DATE '2021-01-10', 4500, 10);
COMMIT;
Integridade Referencial em Ação
Veja como o Oracle protege a integridade dos dados:
-- Tentativa de inserir funcionário em departamento inexistente
INSERT INTO funcionarios VALUES (4, 'Ana Lima', 'ana@empresa.com', SYSDATE, 5500, 99);
-- ERRO: ORA-02291: integrity constraint violated - parent key not found
-- Tentativa de excluir departamento com funcionários vinculados
DELETE FROM departamentos WHERE id_departamento = 10;
-- ERRO: ORA-02292: integrity constraint violated - child record found
-- Para permitir exclusão em cascata, use:
ALTER TABLE funcionarios DROP CONSTRAINT funcionarios_fk;
ALTER TABLE funcionarios ADD CONSTRAINT funcionarios_fk
FOREIGN KEY (departamento_id)
REFERENCES departamentos(id_departamento)
ON DELETE CASCADE;
-- Agora, ao excluir um departamento, seus funcionários também são excluídos
-- Ou use SET NULL para apenas remover a referência:
ALTER TABLE funcionarios DROP CONSTRAINT funcionarios_fk;
ALTER TABLE funcionarios ADD CONSTRAINT funcionarios_fk
FOREIGN KEY (departamento_id)
REFERENCES departamentos(id_departamento)
ON DELETE SET NULL;
Consultando Dados Relacionados
-- Listando funcionários com seus departamentos
SELECT
f.id_funcionario,
f.nome AS funcionario,
f.salario,
d.nome AS departamento,
d.localizacao
FROM funcionarios f
INNER JOIN departamentos d ON f.departamento_id = d.id_departamento
ORDER BY d.nome, f.nome;
-- Resultado:
-- ID_FUNCIONARIO FUNCIONARIO SALARIO DEPARTAMENTO LOCALIZACAO
-- 2 Maria Santos 6500 Recursos Humanos Rio de Janeiro
-- 1 João Silva 5000 Tecnologia São Paulo
-- 3 Pedro Costa 4500 Tecnologia São Paulo
-- Verificando a estrutura das tabelas
DESC funcionarios;
DESC departamentos;
-- Consultando as constraints da tabela
SELECT constraint_name, constraint_type, search_condition
FROM user_constraints
WHERE table_name = 'FUNCIONARIOS';
Resultado Esperado
O que você deve dominar após este tópico:
Identificar estruturas
Reconhecer tabelas, linhas, colunas e seus papéis
Entender relacionamentos
Compreender como tabelas se conectam via chaves
Criar tabelas corretamente
Definir PKs, FKs e constraints apropriadas
Garantir integridade
Usar constraints para proteger dados
Diagnosticar problemas
Identificar violações de integridade referencial
Consultar relacionamentos
Usar JOINs básicos para combinar dados
Exercícios Práticos
Exercício 1: Criação de Tabelas
Crie as tabelas PROJETOS e ALOCACOES seguindo as especificações:
- PROJETOS: id_projeto (PK), nome, data_inicio, data_fim, status
- ALOCACOES: relaciona funcionários a projetos (N:N), com horas_trabalhadas
Ver Solução
-- Tabela de Projetos
CREATE TABLE projetos (
id_projeto NUMBER(10) PRIMARY KEY,
nome VARCHAR2(200) NOT NULL,
data_inicio DATE NOT NULL,
data_fim DATE,
status VARCHAR2(20) DEFAULT 'ATIVO'
CHECK (status IN ('ATIVO', 'PAUSADO', 'CONCLUIDO', 'CANCELADO'))
);
-- Tabela de Alocações (relacionamento N:N)
CREATE TABLE alocacoes (
id_funcionario NUMBER(10) REFERENCES funcionarios(id_funcionario),
id_projeto NUMBER(10) REFERENCES projetos(id_projeto),
horas_trabalhadas NUMBER(6,2) DEFAULT 0,
data_alocacao DATE DEFAULT SYSDATE,
PRIMARY KEY (id_funcionario, id_projeto) -- Chave composta
);
Exercício 2: Consulta com JOIN
Escreva uma consulta que liste todos os funcionários, seus departamentos e os projetos em que estão alocados, mostrando também quem não está em nenhum projeto.
Ver Solução
SELECT
f.nome AS funcionario,
d.nome AS departamento,
p.nome AS projeto,
a.horas_trabalhadas
FROM funcionarios f
INNER JOIN departamentos d ON f.departamento_id = d.id_departamento
LEFT JOIN alocacoes a ON f.id_funcionario = a.id_funcionario
LEFT JOIN projetos p ON a.id_projeto = p.id_projeto
ORDER BY f.nome, p.nome;
Exercício 3: Identificar Problemas
Analise o seguinte código e identifique os problemas de modelagem:
CREATE TABLE pedidos (
numero_pedido VARCHAR2(50),
cliente_nome VARCHAR2(100),
cliente_cpf VARCHAR2(14),
produto1_nome VARCHAR2(100),
produto1_preco NUMBER,
produto2_nome VARCHAR2(100),
produto2_preco NUMBER,
total NUMBER
);
Ver Solução
Problemas identificados:
- Sem chave primária: numero_pedido deveria ser PK
- Redundância: dados do cliente repetidos em cada pedido
- Estrutura fixa: limita a 2 produtos por pedido
- Campo calculado: total não deveria ser armazenado
- Falta normalização: deveria ter tabelas separadas para CLIENTES, PRODUTOS e ITENS_PEDIDO