Criação completa de um banco com dados reais
CREATE TABLE, tipos, constraints (PK, FK, NOT NULL, UNIQUE, CHECK), ALTER, DROP.
Define a estrutura do banco.
INSERT, UPDATE, DELETE, transações (BEGIN/COMMIT/ROLLBACK).
Coloca e modifica os dados.
Hoje vamos juntar tudo: do enunciado até um banco populado.
Uma plataforma web feita para professores acompanharem o próprio grupo de pesquisa — alunos de graduação, mestrado e doutorado — em um só lugar.
Quem orienta vários alunos perde o fio das reuniões, dos prazos de conferência e de quem está trabalhando com quem. Tudo acaba espalhado em planilhas, e-mails e WhatsApp.
Um grafo interativo do grupo: cada aluno é um nó, e as ligações entre eles (co-orientação, colaboração) são as arestas. Clicar em um nó abre o perfil com notas e histórico.
Anotar reuniões, criar lembretes com prazo, acompanhar deadlines de conferências, registrar publicações de cada aluno.
Sistema real, em produção em alumnus.up.railway.app. Código aberto no GitHub.
Cada pesquisador tem nome, e-mail e um status (graduação, mestrado, doutorado, pós-doc). Pertence a um grupo de pesquisa e tem um professor orientador.
Um pesquisador pode estar ligado a outros pesquisadores, com um tipo de relação (co-orientação, colaboração, ex-aluno…). É o que vira aresta no grafo.
O perfil de cada pesquisador tem notas (texto livre + arquivo opcional). Toda nota tem autor e data — e pertence a um pesquisador.
O grupo cria lembretes com texto, data de vencimento e marcador de concluído / pendente. Cada lembrete tem um criador.
Eventos externos com nome, URL e data limite. Cada usuário pode marcar interesse em uma deadline (e cada usuário marca interesse em um mesmo evento no máximo uma vez).
Identificar entidades, atributos e relacionamentos. Definir chaves e cardinalidades.
~15 min, em dupla
Escrever CREATE TABLE para cada entidade, com PKs, FKs e constraints.
~25 min, DB Fiddle
Popular o banco com dados consistentes usando INSERTs em ordem correta.
~25 min
No final, cada dupla mostra o banco populado e justifica uma decisão de modelagem.
CREATE TABLE grupo_pesquisa ( id SERIAL PRIMARY KEY, nome VARCHAR(255) NOT NULL ); CREATE TABLE professor ( id SERIAL PRIMARY KEY, nome VARCHAR(255) NOT NULL, email VARCHAR(255) UNIQUE NOT NULL ); CREATE TABLE pesquisador ( id SERIAL PRIMARY KEY, nome VARCHAR(255) NOT NULL, email VARCHAR(255) UNIQUE, status VARCHAR(20) NOT NULL CHECK (status IN ('graduacao','mestrado','doutorado','postdoc')), grupo_id INTEGER REFERENCES grupo_pesquisa(id), orientador_id INTEGER REFERENCES professor(id) );
Faltam: relacionamento, nota, lembrete, deadline, interesse.
-- Auto-relacionamento (pesquisador ↔ pesquisador) CREATE TABLE relacionamento ( id SERIAL PRIMARY KEY, origem_id INTEGER NOT NULL REFERENCES pesquisador(id), destino_id INTEGER NOT NULL REFERENCES pesquisador(id), tipo VARCHAR(50) NOT NULL, CHECK (origem_id <> destino_id) ); -- N:N com restrição de unicidade (interesse em deadline) CREATE TABLE interesse_deadline ( deadline_id INTEGER NOT NULL REFERENCES deadline(id), usuario_id INTEGER NOT NULL REFERENCES usuario(id), PRIMARY KEY (deadline_id, usuario_id) -- chave composta );
Insira primeiro as tabelas sem FK, depois as que dependem delas. Caso contrário, o banco rejeita o INSERT.
INSERT INTO grupo_pesquisa (nome) VALUES ('LABES'), ('GenAI Lab'); INSERT INTO professor (nome, email) VALUES ('Gustavo Pinto', 'gpinto@ufpa.br'); INSERT INTO pesquisador (nome, email, status, grupo_id, orientador_id) VALUES ('Ana Souza', 'ana@ufpa.br', 'doutorado', 1, 1), ('Bruno Lima', 'bruno@ufpa.br', 'mestrado', 1, 1), ('Carla Mota', 'carla@ufpa.br', 'graduacao', 2, 1); INSERT INTO relacionamento (origem_id, destino_id, tipo) VALUES (1, 2, 'co-orientacao'), (2, 3, 'colaboracao');
Repetir nome do grupo em toda linha de pesquisador é desnormalizado. Use FK para o id do grupo.
Inserir pesquisador antes de criar o grupo quebra a FK. Pense no grafo de dependências.
Guardar nome do orientador no pesquisador, em vez de id, leva a inconsistência.
Pesquisador↔pesquisador é N:N → tabela própria. Pesquisador→orientador é N:1 → FK direta.