Em bancos de dados do Judiciário, a qualidade do esquema impacta diretamente a confiabilidade de informações sensíveis (partes, movimentações, prazos, sigilo, decisões). Normalização e integridade existem para reduzir redundância, evitar inconsistências e garantir que o banco “não aceite” estados inválidos, mesmo quando múltiplos sistemas e usuários gravam dados simultaneamente.
Dependências funcionais (DF): base conceitual da normalização
Dependência funcional descreve uma regra do tipo: em uma relação (tabela), um conjunto de atributos determina outro conjunto. Notação: X → Y, lida como “X determina Y”.
- Exemplo 1 (cadastro de pessoa):
CPF → Nome, DataNascimento. Se o CPF é único, ele determina os demais dados cadastrais. - Exemplo 2 (processo):
NumeroProcesso → Classe, Vara, DataDistribuicao. - Exemplo 3 (movimentação):
(NumeroProcesso, SequenciaMov) → DataMov, TipoMov.
DFs ajudam a identificar anomalias (inserção, atualização e exclusão) e guiam a decomposição em formas normais.
Chaves, superchaves e atributos
- Superchave: conjunto de atributos que identifica univocamente uma linha.
- Chave candidata: superchave mínima (não tem atributo sobrando).
- Chave primária: uma das chaves candidatas escolhida.
- Atributo primo: pertence a alguma chave candidata.
- Atributo não primo: não pertence a nenhuma chave candidata.
Formas normais (visão conceitual): 1FN, 2FN, 3FN e BCNF
1FN (Primeira Forma Normal): atomicidade
Uma tabela está em 1FN quando seus atributos são atômicos (sem listas, conjuntos ou campos “multivalorados” no mesmo atributo) e cada coluna guarda um único tipo de valor.
Violação típica: armazenar vários telefones em uma coluna Telefones como “(11)9999-0000; (11)9888-0000”.
Continue em nosso aplicativo
Você poderá ouvir o audiobook com a tela desligada, ganhar gratuitamente o certificado deste curso e ainda ter acesso a outros 5.000 cursos online gratuitos.
ou continue lendo abaixo...Baixar o aplicativo
Correção: criar uma tabela de telefones relacionada à pessoa.
-- Exemplo conceitual (não é o modelo completo do sistema, apenas ilustra 1FN) Pessoa(CPF, Nome, ...) PessoaTelefone(CPF, Telefone)2FN (Segunda Forma Normal): sem dependência parcial (em chave composta)
Uma tabela em 1FN está em 2FN quando todo atributo não primo depende da chave inteira, e não apenas de parte dela. O problema aparece quando a chave primária é composta.
Exemplo de violação (chave composta):
MovimentacaoProcesso(NumeroProcesso, SeqMov, DataMov, TipoMov, ClasseProcesso, Vara) PK = (NumeroProcesso, SeqMov) DFs: (NumeroProcesso, SeqMov) → DataMov, TipoMov NumeroProcesso → ClasseProcesso, VaraClasseProcesso e Vara dependem apenas de NumeroProcesso (parte da chave), logo há dependência parcial e a tabela não está em 2FN.
Decomposição para 2FN:
Processo(NumeroProcesso, ClasseProcesso, Vara, ...) MovimentacaoProcesso(NumeroProcesso, SeqMov, DataMov, TipoMov, ...) PK MovimentacaoProcesso = (NumeroProcesso, SeqMov) FK MovimentacaoProcesso.NumeroProcesso → Processo.NumeroProcesso3FN (Terceira Forma Normal): sem dependência transitiva (em atributos não chave)
Uma tabela em 2FN está em 3FN quando não há dependência transitiva de atributos não chave: isto é, um atributo não chave não deve determinar outro atributo não chave.
Exemplo de violação:
Processo(NumeroProcesso, CodigoVara, NomeVara, ...) DF: CodigoVara → NomeVara DF: NumeroProcesso → CodigoVaraNomeVara depende de CodigoVara, que por sua vez depende de NumeroProcesso. Isso gera redundância (muitos processos repetindo o nome da vara) e risco de inconsistência (nome divergente para o mesmo código).
Decomposição para 3FN:
Vara(CodigoVara, NomeVara, ...) Processo(NumeroProcesso, CodigoVara, ...) FK Processo.CodigoVara → Vara.CodigoVaraBCNF (Boyce-Codd): determinantes devem ser chaves
BCNF é mais forte que 3FN. Uma tabela está em BCNF quando, para toda DF não trivial X → Y, X é uma superchave. Em termos práticos: quem “determina” algo deve identificar univocamente a linha.
Exemplo clássico adaptado ao contexto: suponha uma tabela que registra designações onde cada Magistrado atua em uma única Vara, mas uma vara pode ter vários magistrados substitutos ao longo do tempo (simplificação).
Designacao(MagistradoId, VaraId, Funcao) DFs: MagistradoId → VaraId (MagistradoId, VaraId) é chave? (depende do cenário) Se a PK for (MagistradoId, Funcao), então MagistradoId não é superchave, mas determina VaraId.Nesse tipo de situação, pode haver 3FN mas não BCNF, exigindo decomposição para eliminar a DF cujo determinante não é superchave. Em provas, o foco é reconhecer a regra: em BCNF, todo determinante é chave.
Como a normalização reduz redundância e evita inconsistências (com exemplo prático)
Considere um cenário sensível: processos com partes e seus dados. Se o banco repete dados cadastrais em várias tabelas, uma atualização parcial pode gerar divergência (ex.: nome da parte diferente em movimentações e em petições), o que é crítico em dados processuais.
Exemplo de redundância e anomalias
Peticao( PeticaoId, NumeroProcesso, CPFParte, NomeParte, EnderecoParte, DataProtocolo, TipoPeticao )- Anomalia de atualização: a parte muda de endereço; se houver 200 petições, é preciso atualizar 200 linhas. Se atualizar 199, o banco fica inconsistente.
- Anomalia de inserção: para cadastrar uma parte sem petição, não há onde inserir (se a tabela “Peticao” for o único local).
- Anomalia de exclusão: ao excluir a última petição, pode-se perder o cadastro da parte.
Decomposição normalizada (ideia)
Parte(CPFParte, NomeParte, EnderecoParte, ...) Processo(NumeroProcesso, ...) Peticao(PeticaoId, NumeroProcesso, DataProtocolo, TipoPeticao, ...) PeticaoParte(PeticaoId, CPFParte, PapelNaPeticao, ...) FKs: Peticao.NumeroProcesso → Processo.NumeroProcesso PeticaoParte.PeticaoId → Peticao.PeticaoId PeticaoParte.CPFParte → Parte.CPFParteAgora o endereço da parte é atualizado em Parte uma única vez, reduzindo redundância e evitando inconsistências.
Integridade: entidade, domínio e referencial
Constraints: regras que o SGBD aplica automaticamente
Constraints são restrições declarativas que impedem gravações inválidas. As principais:
- PRIMARY KEY: garante unicidade e não nulo para identificar linhas.
- UNIQUE: garante unicidade (ex.: número de documento, e-mail institucional).
- NOT NULL: impede ausência de valor em campos obrigatórios (ex.: data de distribuição).
- CHECK: valida regras de domínio (ex.: status permitido, datas coerentes).
- FOREIGN KEY: garante integridade referencial entre tabelas.
Integridade referencial (FK): consistência entre tabelas
Integridade referencial garante que um valor de chave estrangeira exista na tabela referenciada. Ex.: não pode existir movimentação para um processo inexistente.
-- Exemplo genérico de constraints (dialeto pode variar) CREATE TABLE Processo ( NumeroProcesso VARCHAR(25) PRIMARY KEY, DataDistribuicao DATE NOT NULL, SegredoJustica CHAR(1) NOT NULL CHECK (SegredoJustica IN ('S','N')) ); CREATE TABLE Movimentacao ( NumeroProcesso VARCHAR(25) NOT NULL, SeqMov INT NOT NULL, DataMov DATE NOT NULL, TipoMov VARCHAR(30) NOT NULL, PRIMARY KEY (NumeroProcesso, SeqMov), FOREIGN KEY (NumeroProcesso) REFERENCES Processo(NumeroProcesso) );Ações em cascata e restrições de deleção/atualização
Ao definir uma FK, você escolhe o comportamento quando o registro “pai” é alterado/excluído:
- RESTRICT/NO ACTION: impede excluir/alterar se houver filhos (comum para preservar histórico).
- CASCADE: propaga exclusão/alteração (útil em tabelas dependentes sem valor histórico próprio).
- SET NULL/SET DEFAULT: remove a referência (exige coluna permitir nulo ou ter default).
Em dados processuais, é comum evitar CASCADE DELETE em entidades históricas (movimentações, decisões), preferindo inativação lógica (ex.: campo Ativo) e trilhas de auditoria, quando o requisito é preservação.
Triggers: regras procedurais (quando constraints não bastam)
Trigger é um código executado automaticamente em eventos (INSERT/UPDATE/DELETE). Use quando a regra:
- depende de múltiplas tabelas ou de lógica condicional complexa;
- precisa registrar auditoria (quem alterou, quando, antes/depois);
- precisa impedir alterações em estados específicos (ex.: processo arquivado não pode receber nova movimentação).
Exemplo conceitual: impedir inserir movimentação se o processo estiver marcado como arquivado.
-- Pseudocódigo (varia por SGBD) CREATE TRIGGER trg_valida_movimentacao BEFORE INSERT ON Movimentacao FOR EACH ROW BEGIN IF (SELECT Status FROM Processo WHERE NumeroProcesso = NEW.NumeroProcesso) = 'ARQUIVADO' THEN SIGNAL ERROR 'Processo arquivado não pode receber movimentação'; END IF; END;Cuidado em provas e na prática: triggers podem ocultar regras, dificultar manutenção e impactar desempenho. Prefira constraints quando possível.
Transações: consistência sob concorrência e falhas
Transação é uma unidade lógica de trabalho: ou tudo é confirmado (commit) ou tudo é desfeito (rollback). Em sistemas do Judiciário, isso é essencial para evitar estados intermediários (ex.: protocolo de petição sem vínculo com processo, ou movimentação sem registro de auditoria).
Propriedades ACID (essencial para concursos)
- Atomicidade: tudo ou nada.
- Consistência: respeita constraints e regras de integridade.
- Isolamento: transações concorrentes não “se atrapalham” (dependendo do nível de isolamento).
- Durabilidade: após commit, os dados persistem mesmo após falha.
Exemplo prático: protocolo de petição (passo a passo)
Objetivo: inserir uma petição e seus anexos, garantindo que não exista petição “sem anexos obrigatórios” ou anexos “órfãos”.
- Passo 1: iniciar transação.
- Passo 2: inserir registro em
Peticao. - Passo 3: inserir registros em
AnexoPeticao. - Passo 4: se alguma inserção falhar (constraint, FK, validação), executar rollback.
- Passo 5: se tudo ok, commit.
BEGIN TRANSACTION; INSERT INTO Peticao(PeticaoId, NumeroProcesso, DataProtocolo, TipoPeticao) VALUES (1001, '0001234-56.2025.8.01.0001', CURRENT_DATE, 'INICIAL'); INSERT INTO AnexoPeticao(AnexoId, PeticaoId, HashArquivo) VALUES (1, 1001, 'ABC...'); INSERT INTO AnexoPeticao(AnexoId, PeticaoId, HashArquivo) VALUES (2, 1001, 'DEF...'); COMMIT; -- Se qualquer INSERT falhar: ROLLBACK;Níveis de isolamento (visão de prova)
- READ UNCOMMITTED: pode ler dados não confirmados (risco de dirty read).
- READ COMMITTED: evita dirty read; ainda pode ter non-repeatable read.
- REPEATABLE READ: evita non-repeatable read; pode ocorrer phantom read.
- SERIALIZABLE: maior isolamento; reduz phantoms; pode diminuir concorrência.
Em sistemas sensíveis, o nível de isolamento é uma decisão de equilíbrio entre consistência e desempenho, frequentemente combinada com índices e desenho correto de transações.
Exercícios (normalização, decomposição e integridade)
Exercício 1: identificar violações de 1FN
Dada a tabela:
Parte(ParteId, Nome, Telefones, Emails)- a) Indique por que viola 1FN.
- b) Proponha a decomposição mínima para atender 1FN.
- c) Defina PKs e FKs das novas tabelas.
Exercício 2: dependência parcial (2FN)
Considere:
Audiencia(NumeroProcesso, DataAudiencia, Sala, NomeVara, EnderecoVara) PK = (NumeroProcesso, DataAudiencia) Regras: NumeroProcesso → NomeVara, EnderecoVara- a) A tabela está em 2FN? Justifique usando DF.
- b) Decomponha em tabelas que eliminem a dependência parcial.
- c) Indique as FKs necessárias.
Exercício 3: dependência transitiva (3FN)
Considere:
Processo(NumeroProcesso, CodigoClasse, NomeClasse, AssuntoPrincipal)Regra: CodigoClasse → NomeClasse.
- a) Identifique a dependência transitiva.
- b) Decomponha para 3FN.
- c) Aponte qual coluna deve ser FK e para qual tabela.
Exercício 4: caso para BCNF (conceitual)
Considere uma tabela:
Lotacao(ServidorId, UnidadeId, Ramal) Regras: ServidorId → UnidadeId UnidadeId → Ramal (cada unidade tem um ramal único)- a) Quais são as DFs?
- b) A tabela atende 3FN? E BCNF? Explique pela regra do determinante ser superchave.
- c) Proponha decomposição que elimine a violação.
Exercício 5: integridade referencial e ações
Você tem:
Processo(NumeroProcesso PK) Movimentacao(NumeroProcesso FK, SeqMov, ...)- a) O que acontece se tentar inserir uma movimentação com
NumeroProcessoinexistente? - b) Escolha entre
ON DELETE RESTRICTeON DELETE CASCADEpara a FK e justifique no contexto de histórico processual. - c) Proponha um
CHECKpara garantir queSeqMovseja positiva.
Exercício 6: transações e consistência
Um fluxo grava: (1) protocolo da petição, (2) anexos, (3) registro de auditoria. Responda:
- a) Por que isso deve estar em uma única transação?
- b) Dê um exemplo de falha no passo (2) e descreva o estado do banco com e sem rollback.
- c) Qual propriedade ACID é mais diretamente violada se não houver rollback?
Exercício 7: trigger vs constraint
Regra: “Processo com SegredoJustica = 'S' não pode ter DocumentoPublico = 'S' em anexos.”
- a) É possível resolver apenas com
CHECK? Por quê? - b) Modele uma solução com trigger (conceitual), indicando evento e condição.
- c) Cite um risco de usar trigger em excesso.