CREATE TABLE IF NOT EXISTS centro (
id_centro INTEGER PRIMARY KEY,
sigla VARCHAR(10) NOT NULL UNIQUE,
nome_centro VARCHAR(100) NOT NULL
);Hands-on: PostgreSQL na Prática
Nesta seção vamos instalar o PostgreSQL, criar o banco de dados curso da UnDF e popular as tabelas com os dados reais que utilizamos ao longo do material.
Instalação do PostgreSQL
sudo apt update
sudo apt install -y postgresql postgresql-contrib
# Iniciar e habilitar o serviço
sudo systemctl start postgresql
sudo systemctl enable postgresql
# Verificar se está rodando
sudo systemctl status postgresqlApós a instalação, acesse o console interativo:
sudo -u postgres psqlCom Homebrew instalado:
brew install postgresql@16
# Iniciar o serviço
brew services start postgresql@16
# Adicionar ao PATH (cole no ~/.zshrc ou ~/.bash_profile)
echo 'export PATH="/opt/homebrew/opt/postgresql@16/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc
# Acessar o console
psql postgresAlternativa: o app Postgres.app oferece instalação com um clique e não requer Homebrew.
- Acesse postgresql.org/download/windows e baixe o instalador EDB.
- Execute o instalador e siga o assistente. Anote a senha definida para o usuário
postgres. - O pgAdmin 4 (interface gráfica) é instalado junto e pode ser usado no lugar do terminal.
Para usar o terminal psql, abra o SQL Shell (psql) pelo Menu Iniciar e preencha as informações solicitadas (host: localhost, porta: 5432, usuário: postgres).
Alternativa: Caso não possua privilégios de administrador, siga essas instruções.
Criando o Banco de Dados
Conecte-se ao console do PostgreSQL e crie o banco:
CREATE DATABASE curso;Em seguida, conecte-se a ele:
\c cursoNo pgAdmin (Windows/Mac), clique com o botão direito em Databases → Create → Database, informe o nome curso e clique em Save. Depois abra o Query Tool para executar os comandos SQL.
Criando as Tabelas
As tabelas devem ser criadas na ordem correta: primeiro as referenciadas (sem dependências), depois as que referenciam outras.
Tabela centro
Tabela escola
CREATE TABLE IF NOT EXISTS escola (
id_escola INTEGER PRIMARY KEY,
sigla VARCHAR(10) NOT NULL UNIQUE,
nome_escola VARCHAR(100) NOT NULL,
id_centro INTEGER REFERENCES centro(id_centro)
);Tabela curso
CREATE TABLE IF NOT EXISTS curso (
id_curso INTEGER PRIMARY KEY,
sigla_curso VARCHAR(5) NOT NULL UNIQUE,
nome_curso VARCHAR(100) NOT NULL,
id_escola INTEGER REFERENCES escola(id_escola),
n_semestres INTEGER NOT NULL,
carga_horaria INTEGER NOT NULL,
tipo_curso VARCHAR(20) NOT NULL
);Tabela professor
CREATE TABLE IF NOT EXISTS professor (
id_prof INTEGER PRIMARY KEY,
nome VARCHAR(50) NOT NULL,
id_escola INTEGER REFERENCES escola(id_escola),
ch_semanal INTEGER NOT NULL,
salario NUMERIC(10,2) NOT NULL
);Tabela aluno
CREATE TABLE IF NOT EXISTS aluno (
id_aluno INTEGER PRIMARY KEY,
nome VARCHAR(50) NOT NULL,
id_curso INTEGER REFERENCES curso(id_curso),
ano_ingresso INTEGER NOT NULL
);Tabela disciplina
CREATE TABLE IF NOT EXISTS disciplina (
id_disciplina INTEGER PRIMARY KEY,
nome_disciplina VARCHAR(100) NOT NULL,
id_curso INTEGER REFERENCES curso(id_curso),
semestre INTEGER NOT NULL,
carga_horaria INTEGER NOT NULL CHECK (carga_horaria > 0)
);Tabela prereq
CREATE TABLE IF NOT EXISTS prereq (
id_disciplina INTEGER REFERENCES disciplina(id_disciplina),
id_prereq INTEGER REFERENCES disciplina(id_disciplina),
PRIMARY KEY (id_disciplina, id_prereq)
);Tabela ministra
CREATE TABLE IF NOT EXISTS ministra (
id_disciplina INTEGER REFERENCES disciplina(id_disciplina),
ano INTEGER NOT NULL,
semestre INTEGER NOT NULL,
turma INTEGER NOT NULL,
id_prof INTEGER REFERENCES professor(id_prof),
horario VARCHAR(50),
sala VARCHAR(20),
PRIMARY KEY (id_disciplina, ano, semestre, turma)
);Tabela matricula_disciplina
CREATE TABLE IF NOT EXISTS matricula_disciplina (
id_disciplina INTEGER NOT NULL,
ano INTEGER NOT NULL,
semestre INTEGER NOT NULL,
turma INTEGER NOT NULL,
id_aluno INTEGER REFERENCES aluno(id_aluno),
nota NUMERIC(4,1),
aprovado SMALLINT,
PRIMARY KEY (id_disciplina, ano, semestre, turma, id_aluno),
FOREIGN KEY (id_disciplina, ano, semestre, turma)
REFERENCES ministra(id_disciplina, ano, semestre, turma)
);Carregando os Dados
Antes de inserir, limpamos os dados anteriores (respeitando a ordem das chaves estrangeiras):
TRUNCATE matricula_disciplina, ministra, prereq, disciplina,
aluno, professor, curso, escola, centro CASCADE;Centros
INSERT INTO centro (id_centro, sigla, nome_centro) VALUES
(1, 'COCHCMA', 'Ciências Humanas, Cidadania e Meio Ambiente'),
(2, 'COEMAG', 'Centro de Educação, Magistério e Artes'),
(3, 'COETI', 'Centro de Engenharias, Tecnologia e Inovação');Escolas
INSERT INTO escola (id_escola, sigla, nome_escola, id_centro) VALUES
(11, 'ESG', 'Escola Superior de Gestão', 1),
(21, 'EEMA', 'Escola de Educação, Magistério e Arte', 2),
(31, 'ESETI', 'Escola Superior de Engenharias, Tecnologia e Inovação', 3);Cursos
INSERT INTO curso (id_curso, sigla_curso, nome_curso, id_escola, n_semestres, carga_horaria, tipo_curso) VALUES
(311, 'ENS', 'Engenharia de Software', 31, 8, 3200, 'bacharelado'),
(111, 'ECO', 'Ciências Econômicas', 11, 8, 3000, 'bacharelado'),
(211, 'PED', 'Pedagogia', 21, 8, 3410, 'licenciatura');Professores
INSERT INTO professor (id_prof, nome, id_escola, ch_semanal, salario) VALUES
(21200001, 'Eduarda Souza', 21, 20, 3200),
(21400002, 'Felipe Araujo', 21, 40, 6400),
(31200001, 'Gustavo Costa', 31, 20, 3300),
(31400002, 'Helena Carvalho', 31, 40, 6700),
(31200003, 'Igor Melo', 31, 20, 3100),
(11400001, 'Bruno Teixeira', 11, 40, 6500),
(11400002, 'Carla Pinto', 11, 40, 6600);Alunos
INSERT INTO aluno (id_aluno, nome, id_curso, ano_ingresso) VALUES
(2023111001, 'Beatriz Carvalho', 111, 2023),
(2023111002, 'Lucas Santos', 111, 2023),
(2024111001, 'Gabriel Ribeiro', 111, 2024),
(2024111002, 'Fernanda Martins', 111, 2024),
(2025111001, 'Rodrigo Lima', 111, 2025),
(2025111002, 'Camila Teixeira', 111, 2025),
(2023211001, 'Amanda Moreira', 211, 2023),
(2023211002, 'Thiago Gomes', 211, 2023),
(2024211001, 'Carolina Lima', 211, 2024),
(2024211002, 'Rafael Costa', 211, 2024),
(2025211001, 'Vinícius Pereira', 211, 2025),
(2025211002, 'Letícia Souza', 211, 2025),
(2023311001, 'Matheus Silva', 311, 2023),
(2023311002, 'Larissa Araújo', 311, 2023),
(2024311001, 'Pedro Carvalho', 311, 2024),
(2024311002, 'Isabela Freitas', 311, 2024),
(2025311001, 'Diego Correia', 311, 2025),
(2025311002, 'Juliana Nunes', 311, 2025);Disciplinas
INSERT INTO disciplina (id_disciplina, nome_disciplina, id_curso, semestre, carga_horaria) VALUES
(1110201, 'História Econômica Geral', 111, 2, 75),
(1110202, 'Culturas Digitais', 111, 2, 60),
(1110401, 'Microeconomia 2', 111, 4, 75),
(1110402, 'Macroeconomia 2', 111, 4, 95),
(1110601, 'Economia Brasileira', 111, 6, 75),
(1110602, 'Orçamento e Finanças Públicas', 111, 6, 75),
(1110801, 'Monografia', 111, 8, 100),
(1110802, 'Desenvolvimento Econômico', 111, 8, 90),
(2110201, 'Desenvolvimento Humano', 211, 2, 60),
(2110202, 'Didática Geral', 211, 2, 60),
(2110401, 'Eletiva I', 211, 4, 80),
(2110402, 'Fundamentos e Orientações Metodológicas - Ed. Infantil - BNCC', 211, 4, 80),
(2110601, 'Eletiva II', 211, 6, 80),
(2110602, 'Educação do Campo, Indígena e Quilombola', 211, 6, 40),
(2110801, 'Tecnologia Educacional - Design', 211, 8, 60),
(2110802, 'Estatística Aplicada', 211, 8, 50),
(3110201, 'Bases da Eng. de Software 2', 311, 2, 150),
(3110202, 'Projeto Aplicado 2 - site WEB', 311, 2, 120),
(3110401, 'Bases da Eng. de Software 4', 311, 4, 180),
(3110402, 'Projeto Aplicado 4 - blockchain', 311, 4, 120),
(3110601, 'Bases da Eng. de Software 6', 311, 6, 150),
(3110602, 'Projeto Aplicado 6 - Machine Learning', 311, 6, 120),
(3110801, 'Bases da Eng. de Software 8', 311, 8, 100),
(3110802, 'Projeto Aplicado 8 - Sistema em Tempo Real', 311, 8, 160);Pré-requisitos
INSERT INTO prereq (id_disciplina, id_prereq) VALUES
(3110401, 3110201),
(3110402, 3110202),
(3110601, 3110401),
(3110601, 3110402),
(3110602, 3110402),
(3110801, 3110601),
(3110802, 3110601),
(3110802, 3110602),
(1110401, 1110201),
(1110601, 1110401),
(1110602, 1110402),
(1110801, 1110601),
(1110801, 1110602),
(2110401, 2110201),
(2110601, 2110401),
(2110801, 2110601);Turmas ministradas
INSERT INTO ministra (id_disciplina, ano, semestre, turma, id_prof, horario, sala) VALUES
(2110201, 2023, 2, 1, 21200001, '2f-19:00-21:30', 'EEMA-SALA-003'),
(2110202, 2023, 2, 1, 21200001, '2f-19:00-21:30', 'EEMA-SALA-004'),
(2110201, 2024, 2, 1, 21200001, '3f-19:00-21:30', 'EEMA-SALA-003'),
(2110202, 2024, 2, 1, 21200001, '3f-19:00-21:30', 'EEMA-SALA-004'),
(2110401, 2024, 2, 1, 21200001, '2f-19:00-22:20', 'EEMA-SALA-001'),
(2110402, 2024, 2, 1, 21200001, '2f-19:00-22:20', 'EEMA-SALA-002'),
(2110201, 2025, 2, 1, 21200001, '3f-19:00-21:30', 'EEMA-SALA-001'),
(2110202, 2025, 2, 1, 21400002, '3f-19:00-21:30', 'EEMA-SALA-002'),
(2110401, 2025, 2, 1, 21200001, '2f-19:00-22:20', 'EEMA-SALA-003'),
(2110402, 2025, 2, 1, 21200001, '2f-19:00-22:20', 'EEMA-SALA-004'),
(2110601, 2025, 2, 1, 21200001, '2f-19:00-22:20', 'EEMA-SALA-001'),
(2110602, 2025, 2, 1, 21200001, '2f-19:00-20:40', 'EEMA-SALA-046'),
(3110201, 2023, 2, 1, 31200001, '2f-13:45-16:55/4f-13:45-16:50', 'ESETI-SALA-001'),
(3110202, 2023, 2, 1, 31200001, '2f-13:45-16:15/4f-13:45-16:15', 'ESETI-SALA-003'),
(3110201, 2024, 2, 1, 31200001, '2f-13:45-16:55/4f-13:45-16:50', 'ESETI-SALA-003'),
(3110202, 2024, 2, 1, 31400002, '2f-13:45-16:15/4f-13:45-16:15', 'ESETI-SALA-006'),
(3110401, 2024, 2, 1, 31200001, '2f-13:45-17:30/4f-13:45-17:30', 'ESETI-SALA-001'),
(3110402, 2024, 2, 1, 31400002, '2f-13:45-16:15/4f-13:45-16:15', 'ESETI-SALA-005'),
(3110201, 2025, 2, 1, 31200001, '2f-13:45-16:55/4f-13:45-16:50', 'ESETI-SALA-005'),
(3110202, 2025, 2, 1, 31400002, '2f-13:45-16:15/4f-13:45-16:15', 'ESETI-SALA-010'),
(3110401, 2025, 2, 1, 31200001, '2f-13:45-17:30/4f-13:45-17:30', 'ESETI-SALA-001'),
(3110402, 2025, 2, 1, 31200003, '2f-13:45-16:15/4f-13:45-16:15', 'ESETI-SALA-008'),
(3110601, 2025, 2, 1, 31400002, '2f-13:45-16:55/4f-13:45-16:50', 'ESETI-SALA-003'),
(3110602, 2025, 2, 1, 31200003, '2f-13:45-16:15/4f-13:45-16:15', 'ESETI-SALA-007'),
(1110201, 2023, 2, 1, 11400001, '2f-7:30-10:40', 'ESG-SALA-005'),
(1110202, 2023, 2, 1, 11400001, '2f-7:30-10:00', 'ESG-SALA-012'),
(1110201, 2024, 2, 1, 11400001, '2f-7:30-10:40', 'ESG-SALA-013'),
(1110202, 2024, 2, 1, 11400001, '3f-10:00-12:30', 'ESG-SALA-001'),
(1110401, 2024, 2, 1, 11400001, '2f-7:30-10:40', 'ESG-SALA-009'),
(1110402, 2024, 2, 1, 11400001, '2f-7:30-11:30', 'ESG-SALA-001'),
(1110201, 2025, 2, 1, 11400001, '2f-7:30-10:40', 'ESG-SALA-025'),
(1110202, 2025, 2, 1, 11400002, '3f-10:00-12:30', 'ESG-SALA-007'),
(1110401, 2025, 2, 1, 11400001, '2f-7:30-10:40', 'ESG-SALA-021'),
(1110402, 2025, 2, 1, 11400001, '2f-7:30-11:30', 'ESG-SALA-005'),
(1110601, 2025, 2, 1, 11400001, '2f-7:30-10:40', 'ESG-SALA-015'),
(1110602, 2025, 2, 1, 11400002, '2f-7:30-10:40', 'ESG-SALA-016');Matrículas em disciplinas
INSERT INTO matricula_disciplina (id_disciplina, ano, semestre, turma, id_aluno, nota, aprovado) VALUES
(3110201, 2023, 2, 1, 2023311001, 9.0, 1),
(3110202, 2023, 2, 1, 2023311001, 7.4, 1),
(3110401, 2024, 2, 1, 2023311001, 7.5, 1),
(3110402, 2024, 2, 1, 2023311001, 6.6, 1),
(3110601, 2025, 2, 1, 2023311001, 4.1, 0),
(3110602, 2025, 2, 1, 2023311001, 8.7, 1),
(3110201, 2023, 2, 1, 2023311002, 6.1, 1),
(3110202, 2023, 2, 1, 2023311002, 6.3, 1),
(3110401, 2024, 2, 1, 2023311002, 9.0, 1),
(3110402, 2024, 2, 1, 2023311002, 8.6, 1),
(3110601, 2025, 2, 1, 2023311002, 0.3, 0),
(3110602, 2025, 2, 1, 2023311002, 7.7, 1),
(3110201, 2024, 2, 1, 2024311002, 4.3, 0),
(3110202, 2024, 2, 1, 2024311002, 7.2, 1),
(3110401, 2025, 2, 1, 2024311002, 7.7, 1),
(3110402, 2025, 2, 1, 2024311002, 0.4, 0),
(3110201, 2025, 2, 1, 2025311001, 6.1, 1),
(3110202, 2025, 2, 1, 2025311001, 6.8, 1),
(3110201, 2025, 2, 1, 2025311002, 1.9, 0),
(3110202, 2025, 2, 1, 2025311002, 6.1, 1),
(1110201, 2023, 2, 1, 2023111001, 9.8, 1),
(1110202, 2023, 2, 1, 2023111001, 8.8, 1),
(1110201, 2024, 2, 1, 2024111001, 7.9, 1),
(1110202, 2024, 2, 1, 2024111001, 8.5, 1),
(1110401, 2025, 2, 1, 2024111001, 6.1, 1),
(1110402, 2025, 2, 1, 2024111001, 6.5, 1),
(1110201, 2024, 2, 1, 2024111002, 3.4, 0),
(1110202, 2024, 2, 1, 2024111002, 6.4, 1),
(1110401, 2025, 2, 1, 2024111002, 6.1, 1),
(1110402, 2025, 2, 1, 2024111002, 7.7, 1),
(1110201, 2025, 2, 1, 2025111001, 7.1, 1),
(1110202, 2025, 2, 1, 2025111001, 6.1, 1),
(1110201, 2025, 2, 1, 2025111002, 6.1, 1),
(1110202, 2025, 2, 1, 2025111002, 9.9, 1),
(2110201, 2023, 2, 1, 2023211001, 8.4, 1),
(2110202, 2023, 2, 1, 2023211001, 8.2, 1),
(2110401, 2024, 2, 1, 2023211001, 8.5, 1),
(2110402, 2024, 2, 1, 2023211001, 8.8, 1),
(2110601, 2025, 2, 1, 2023211001, 6.1, 1),
(2110602, 2025, 2, 1, 2023211001, 6.2, 1),
(2110201, 2023, 2, 1, 2023211002, 6.3, 1),
(2110202, 2023, 2, 1, 2023211002, 6.8, 1),
(2110401, 2024, 2, 1, 2023211002, 6.1, 1),
(2110402, 2024, 2, 1, 2023211002,10.0, 1),
(2110601, 2025, 2, 1, 2023211002, 1.3, 0),
(2110602, 2025, 2, 1, 2023211002, 6.1, 1),
(2110201, 2024, 2, 1, 2024211001, 7.0, 1),
(2110202, 2024, 2, 1, 2024211001, 9.7, 1),
(2110401, 2025, 2, 1, 2024211001, 9.2, 1),
(2110402, 2025, 2, 1, 2024211001, 6.1, 1),
(2110201, 2024, 2, 1, 2024211002, 7.1, 1),
(2110202, 2024, 2, 1, 2024211002, 8.7, 1),
(2110401, 2025, 2, 1, 2024211002, 7.6, 1),
(2110402, 2025, 2, 1, 2024211002, 7.6, 1),
(2110201, 2025, 2, 1, 2025211001, 6.1, 1),
(2110202, 2025, 2, 1, 2025211001, 7.0, 1),
(2110201, 2025, 2, 1, 2025211002, 8.4, 1),
(2110202, 2025, 2, 1, 2025211002, 7.4, 1);Outra opção, no PostgreSQL, é utilizar o comando COPY para importar os dados diretamente de arquivos CSV. Por exemplo:
COPY matricula_disciplina (id_disciplina, ano, semestre, turma, id_aluno, nota, aprovado)
FROM '/caminho/para/matricula_disciplina.csv' DELIMITER ';' CSV HEADER;Verificando os Dados
Todos os cursos
SELECT id_curso, sigla_curso, nome_curso, id_escola, tipo_curso
FROM curso
ORDER BY id_curso;| id_curso | sigla_curso | nome_curso | id_escola | tipo_curso |
|---|---|---|---|---|
| 111 | ECO | Ciências Econômicas | 11 | bacharelado |
| 211 | PED | Pedagogia | 21 | licenciatura |
| 311 | ENS | Engenharia de Software | 31 | bacharelado |
Professores por escola
SELECT id_escola, COUNT(*) AS n_professores
FROM professor
GROUP BY id_escola
ORDER BY id_escola;| id_escola | n_professores |
|---|---|
| 11 | 2 |
| 21 | 2 |
| 31 | 3 |
Disciplinas com carga horária acima de 100 h
SELECT id_disciplina, nome_disciplina, id_curso, carga_horaria
FROM disciplina
WHERE carga_horaria > 100
ORDER BY carga_horaria DESC;| id_disciplina | nome_disciplina | id_curso | carga_horaria |
|---|---|---|---|
| 3110401 | Bases da Eng. de Software 4 | 311 | 180 |
| 3110802 | Projeto Aplicado 8 - Sistema em Tempo Real | 311 | 160 |
| 3110601 | Bases da Eng. de Software 6 | 311 | 150 |
| 3110201 | Bases da Eng. de Software 2 | 311 | 150 |
| 3110402 | Projeto Aplicado 4 - blockchain | 311 | 120 |
| 3110202 | Projeto Aplicado 2 - site WEB | 311 | 120 |
| 3110602 | Projeto Aplicado 6 - Machine Learning | 311 | 120 |
Alunos de Engenharia de Software ingressantes em 2023
SELECT id_aluno, nome, ano_ingresso
FROM aluno
WHERE id_curso = 311 AND ano_ingresso = 2023;| id_aluno | nome | ano_ingresso |
|---|---|---|
| 2023311001 | Matheus Silva | 2023 |
| 2023311002 | Larissa Araújo | 2023 |
Para remover todas as tabelas e recriar do zero:
DROP TABLE IF EXISTS matricula_disciplina, ministra, prereq,
disciplina, aluno, professor,
curso, escola, centro CASCADE;