Banco de Dados II — 2026.2

Aula 1
Apresentação e Armazenamento

👨‍🏫 Prof. Gustavo Pinto 🏛️ UFPA 📅 3 de setembro de 2026 🕐 7h30 – 9h

Bem-vindos!

Não tivemos aula em 01/09, então hoje abrimos a disciplina e já entramos no primeiro tema.

Em Banco de Dados I, escrevemos SQL

Aqui, escrevemos o programa que executa o SQL.

O critério de pronto

Devemos construir um minidb, em que podemos executar um SELECT com WHERE, dentro de uma transação que volta ao ar consistente depois de levar um kill -9 no meio do commit.

Sacou? O conteúdo do semestre foi escolhido de trás para frente, a partir dessa frase.

A anatomia de um SGBD

📝

Parser e catálogo

Do texto SQL a uma árvore que o programa entende

⚙️

Executor

Operadores que produzem linhas, um de cada vez

🌱

Índice e métodos de acesso

Achar a linha sem varrer a tabela inteira

💾

Buffer e armazenamento

Páginas em memória, páginas em disco, e o log

Vamos construir de baixo para cima, porque cada camada depende da anterior. A camada de baixo começa hoje.

O minidb 0.0

Cinquenta linhas de Python.

$ python3 hello.py dados.db < demo.sql
CREATE TABLE aluno (id, matricula, nome);
OK
INSERT INTO aluno VALUES (1, 20260001, Ana);
OK 1
SELECT * FROM aluno WHERE id = 2;
2|20260002|Bruno
(1 linha)

Cria tabela, insere, filtra e guarda em disco. É um banco de dados, e é também lento, esquecido e frágil. Consertar cada um desses defeitos é um módulo do semestre.

Os sete módulos

Uma aula teórica e duas de laboratório por módulo.

O que não vamos construir

Esses temas viram seminários em 24/11 e 26/11, sorteados em 10/11, respondendo sempre à mesma pergunta: o que precisaria mudar no minidb para ter isso?

A linguagem é escolha de vocês

Não estamos competindo em desempenho com o PostgreSQL. A escolha é sobre o que vocês querem aprender.

O que eu forneço é o contrato

O minidb lê comandos da entrada padrão e escreve o resultado na saída padrão, em formato definido. Assim os mesmos testes valem para qualquer linguagem.

$ ./minidb dados.db < consultas.sql
CREATE TABLE aluno (id INT, matricula INT);
OK
INSERT INTO aluno VALUES (1, 20260001);
OK 1
SELECT * FROM aluno WHERE id = 1;
1|20260001
(1 linha)

Repositório e registro de avanços

Sete commits gigantes, um por módulo, na véspera de cada prazo, contam a história de um trabalho que não aconteceu.

Avaliação

🧩 Módulos M1 a M7Dez pontos cada, do M1 ao M770 pts
🎤 Defesa oralIndividual, em 01/12 e 03/1220 pts
📚 SeminárioEm dupla, em 24/11 ou 26/1110 pts

Cada módulo: metade pelos testes de aceitação, um terço pela qualidade do código e do histórico, o restante pelo NOTES.md.

Sobre ferramentas de LLM

Um agente escreve uma árvore B+ em trinta segundos, e ela até passa nos testes.

Cronograma · setembro e outubro

#DataDiaConteúdo
T103/09QuiApresentação e armazenamento
08 e 10/09CBSoft 2026, sem aula
I115 e 17/09Laboratório M1. Entrega em 17/09
T222/09TerCache de páginas
I224 e 29/09Laboratório M2. Entrega em 29/09
T301/10QuiÁrvore B+
I306 e 08/10Laboratório M3. Entrega em 08/10
T413/10TerParser e catálogo
I415 e 20/10Laboratório M4. Entrega em 20/10
T522/10QuiExecutor
I527 e 29/10Laboratório M5. Entrega em 29/10

Cronograma · novembro e dezembro

#DataDiaConteúdo
T603/11TerTransações
I605 e 10/11Laboratório M6. Entrega e sorteio dos seminários em 10/11
T712/11QuiRecuperação
I717 e 19/11Laboratório M7. Entrega em 19/11
S124/11TerSeminários, primeira metade
S226/11QuiSeminários, segunda metade
DO01 e 03/12Defesa oral individual
08/12TerNossa Senhora da Conceição, sem aula
PF10/12QuiApresentações finais
15, 17 e 22/12Buffer, fechamento e notas

Parte 2
Armazenamento

A camada de baixo. É por onde a gente começa a construir

O disco não sabe o que é uma linha

Você pede 8 bytes ao disco. Quanto ele te entrega?

Quem transforma bloco em linha é o programa que vocês vão escrever.

Por que página, e não linha?

Ler 8 bytes do disco custa quase o mesmo que ler 8 kilobytes. Por quê?

A página por dentro

Uma página é um vetor de bytes, e nada além disso. O que dá sentido a ela é saber onde cada coisa começa.

página de 4096 bytes
+-----------+-------+-------+-------+------------------+
| cabeçalho | reg 0 | reg 1 | reg 2 |   espaço livre   |
+-----------+-------+-------+-------+------------------+
   16 bytes   8 b     8 b     8 b

O cabeçalho diz quantos slots estão ocupados. O resto são registros, um atrás do outro.

Registro de tamanho fixo

Todo registro da tabela ocupa exatamente o mesmo número de bytes.

CREATE TABLE aluno (id INT, matricula INT);

  id           4 bytes
  matricula    4 bytes
  registro     8 bytes,  sempre o mesmo

Custa espaço, e proíbe texto de tamanho livre. Em troca, achar uma linha vira uma conta.

E o arquivo, como fica?

dados.db
+-----------+-----------+-----------+-----------+
| página 0  | página 1  | página 2  | página 3  |  ...
| metadados |  registros, registros, registros  |
+-----------+-----------+-----------+-----------+
   4096 b      4096 b      4096 b      4096 b

Sem ordem nenhuma

Heap file, do inglês, é o arquivo em que a linha nova vai para a primeira posição livre que aparecer.

Esse preço é exatamente o que a árvore B+ vai resolver, lá no M3.

O endereço de uma linha

Cada linha tem um endereço dentro do arquivo: o par (página, slot). É ele que o índice vai guardar, lá no M3.

Esse par tem nome. Procurem por RID, do inglês record identifier.

Glossário de hoje

Arquivo contém páginas, página contém slots, e o slot guarda um registro. Escolhemos 4096 bytes para uma página cair em cima de um bloco, e não em cima de dois.

O que os bancos de verdade fazem

Página com diretório de slots

Slots crescem de uma ponta, dados da outra. Permite linha de tamanho variável.

não faremos

Mapa de bits de nulos

Um bit por coluna diz se o valor está ausente, sem gastar o espaço do campo.

não faremos

Layout por coluna

Guarda cada coluna junta, em vez de cada linha junta. Domina análise de dados.

vira seminário

Tamanho fixo custa espaço e proíbe VARCHAR livre. Ganhamos o semestre inteiro em troca.

O M1 cabe em três funções

No fim das contas, o módulo inteiro é isto:

le_pagina(n)               →  devolve os 4096 bytes da página n
escreve_pagina(n, bytes)   →  grava os 4096 bytes na página n
insere(registro)           →  acha espaço, grava, devolve o RID

O resto do semestre é construído em cima dessas três. Se elas estiverem certas, o M2 e o M3 vêm bem mais tranquilos.

Exercício: comecem o minidb

Hoje vocês escrevem as duas primeiras funções do M1. Página de 4096 bytes, cabeçalho de 16, registro de 8.

Entrega até 15/09, junto com a escolha da linguagem e a saída do script de testes falhando por inteiro. Em 08 e 10/09 não há aula, por conta do CBSoft 2026.