Partilhar: WhatsApp
aulify
UC UC00602 · T. Desenv. Software, T. Inform. Gestão

Ficha 02 · Normalização e restrições

1FN, 2FN, 3FN, FK, CHECK e CASCADE
Versão · Aluno
Tempo · 45 minutos
Cotação · 100 pontos
Aluno(a)
Turma
Data
Objectivos da ficha

Parte I · Formas normais

Exercício 1 · Identificar violação (15 pts)

Para cada caso, indica que forma normal é violada e como corrigir:

a)

id aluno disciplinas
1 João Matemática, Português, Inglês

b)

encomenda_id produto_id nome_produto qty
1 5 Caneta 10

c)

aluno_id cod_postal localidade
42 1000-001 Lisboa

a) Viola 1FNdisciplinas não é atómico. Corrigir: tabela Aluno_Disciplina (aluno_id, disciplina_id).

b) Viola 2FNnome_produto depende só de produto_id, não da chave composta. Corrigir: mover nome_produto para tabela Produto.

c) Viola 3FNlocalidade depende de cod_postal, não directamente do aluno (dependência transitiva). Corrigir: tabela CodigoPostal (cod_postal PK, localidade).

Exercício 2 · Normalizar (20 pts)

A tabela seguinte regista vendas:

venda_id data cliente_id nome_cliente email_cliente produto_id nome_produto preco qty

Identifica todos os problemas e propõe modelo normalizado:

Problemas: 1. nome_cliente, email_cliente dependem de cliente_id, não da venda → mover para tabela Cliente. 2. nome_produto, preco dependem de produto_id → mover para tabela Produto. 3. Uma venda só tem um produto na estrutura mostrada; provavelmente queremos uma venda com vários produtos → introduzir tabela VendaItem.

Modelo normalizado:

Cliente (id PK, nome, email)
Produto (id PK, nome, preco)
Venda (id PK, data, cliente_id FK)
VendaItem (
  venda_id FK,
  produto_id FK,
  qty,
  preco_unit,  -- preço no momento da venda
  PK (venda_id, produto_id)
)

Notar: preco_unit em VendaItem é necessário porque o preço actual do produto pode ter mudado desde a venda.

Exercício 3 · Quando desnormalizar (10 pts)

a) Em que situações pode fazer sentido desnormalizar uma BD bem normalizada?

b) Que cuidados ter quando se desnormaliza?

a) Situações: - Relatórios e BI com queries massivas que de outro modo exigiriam muitos JOINs. - Caches de valores calculados (totais, contagens). - Tabelas históricas/snapshot onde dados não devem mudar mesmo que o "pai" mude (ex.: nome do cliente numa fatura emitida).

b) Cuidados: - Justificar com medição (perfil de query antes/depois). - Documentar que dados estão duplicados e onde. - Triggers ou aplicação para manter cópias consistentes, ou aceitar consistência eventual. - Não desnormalizar prematuramente — é mais fácil desnormalizar depois do que renormalizar.

Parte II · Restrições

Exercício 4 · Definir restrições (20 pts)

Para a tabela Produto (id, nome, preco, stock, cat_id), escreve SQL com todas as restrições adequadas:

CREATE TABLE Produto (
  id INT PRIMARY KEY AUTO_INCREMENT,
  nome VARCHAR(150) NOT NULL UNIQUE,
  preco DECIMAL(10,2) NOT NULL CHECK (preco >= 0),
  stock INT NOT NULL DEFAULT 0 CHECK (stock >= 0),
  cat_id INT,
  FOREIGN KEY (cat_id) REFERENCES Categoria(id) ON DELETE SET NULL
);

Decisões: - id PK auto-increment — chave artificial. - nome UNIQUE — não queremos dois produtos com nome igual. - preco DECIMAL — exacto, não usar FLOAT para dinheiro. - CHECK (preco >= 0) e CHECK (stock >= 0) — evita valores absurdos. - cat_id permite NULL (produto pode existir sem categoria); SET NULL se categoria for apagada.

Exercício 5 · Acções referenciais (15 pts)

Para cada relação, indica a acção ON DELETE mais apropriada e justifica:

a) Apagar Encomenda → o que fazer com EncomendaItem?

b) Apagar Cliente → o que fazer com Encomenda?

c) Apagar Categoria → o que fazer com Produto?

d) Apagar Autor → o que fazer com Livro_Autor (tabela de associação)?

a) CASCADE — itens da encomenda não fazem sentido sem a encomenda. Apaga-se tudo junto.

b) RESTRICT — não apagar cliente com encomendas históricas; a alternativa é "soft delete" (campo apagado = true). Apagar é raro em sistemas reais (RGPD pode obrigar mas com cuidados).

c) SET NULL — produto continua a existir mesmo sem categoria. Alternativa: criar categoria "Outros" como default.

d) CASCADE — entradas em Livro_Autor referindo autor apagado deixam de fazer sentido.

Parte III · Cenário

Exercício 6 · Sistema de gestão escolar (20 pts)

Pretende-se gerir disciplinas, alunos, professores, turmas e notas.

a) Identifica 5+ entidades.

b) Desenha pelo menos uma relação 1:N e uma N:M com tabela de associação.

c) Indica restrições importantes em pelo menos 3 colunas.

a) Entidades: - Aluno, Professor, Turma, Disciplina, Inscricao (associação Aluno-Disciplina), Aula (opcional).

b) Modelo:

CREATE TABLE Turma (
  id INT PRIMARY KEY AUTO_INCREMENT,
  codigo VARCHAR(10) UNIQUE NOT NULL,
  ano_lectivo VARCHAR(9) NOT NULL  -- ex.: "2026/2027"
);

CREATE TABLE Aluno (
  id INT PRIMARY KEY AUTO_INCREMENT,
  numero VARCHAR(10) UNIQUE NOT NULL,
  nome VARCHAR(150) NOT NULL,
  data_nascimento DATE,
  turma_id INT,
  FOREIGN KEY (turma_id) REFERENCES Turma(id) ON DELETE SET NULL
);
-- Aluno-Turma é 1:N: cada aluno numa turma, turma tem vários alunos.

CREATE TABLE Disciplina (
  id INT PRIMARY KEY AUTO_INCREMENT,
  codigo VARCHAR(20) UNIQUE NOT NULL,
  nome VARCHAR(100) NOT NULL,
  professor_id INT,
  FOREIGN KEY (professor_id) REFERENCES Professor(id)
);

CREATE TABLE Inscricao (
  aluno_id INT,
  disciplina_id INT,
  ano_lectivo VARCHAR(9),
  nota DECIMAL(4,2) CHECK (nota >= 0 AND nota <= 20),
  PRIMARY KEY (aluno_id, disciplina_id, ano_lectivo),
  FOREIGN KEY (aluno_id) REFERENCES Aluno(id) ON DELETE CASCADE,
  FOREIGN KEY (disciplina_id) REFERENCES Disciplina(id) ON DELETE RESTRICT
);
-- Aluno-Disciplina é N:M com atributos próprios (nota, ano).

c) Restrições importantes: - Aluno.numero UNIQUE NOT NULL — número de aluno único. - Disciplina.codigo UNIQUE NOT NULL. - Inscricao.nota CHECK (nota >= 0 AND nota <= 20) — escala portuguesa. - Inscricao PK composta com ano_lectivo permite aluno repetir disciplina noutro ano. - Aluno.data_nascimento pode adicionar CHECK (data_nascimento < CURRENT_DATE).