Aqui, escrevemos o programa que executa o SQL.
SELECT e o resultadoDevemos 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.
Do texto SQL a uma árvore que o programa entende
Operadores que produzem linhas, um de cada vez
Achar a linha sem varrer a tabela inteira
Páginas em memória, páginas em disco, e o log
Vamos construir de baixo para cima, porque cada camada depende da anterior.
O sistema operacional já tem cache de arquivo. Por que não usar só ele?
BEGIN, COMMIT, ROLLBACKUma aula teórica e duas de laboratório por módulo.
VARCHAR livre, mapa de nulosORDER BY e agregaçãoToda apresentação responde à mesma pergunta: o que precisaria mudar no minidb para ter isso?
Não estamos competindo em desempenho com o PostgreSQL. A escolha é sobre o que vocês querem aprender.
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)
O prazo de cada módulo é a data de publicação da referência. Depois dela, não há pontos.
NOTES.mdNOTES.md, um parágrafo sobre a decisão de projeto mais difícil daquele móduloSete commits gigantes, um por módulo, na véspera de cada prazo, contam a história de um trabalho que não aconteceu.
| 🧩 Módulos M1 a M7 | M3 e M7 valem 10, os outros cinco valem 8 | 60 pts |
| 🎤 Defesa oral | Individual, em 01/12 e 03/12 | 20 pts |
| 📚 Seminário | Em dupla, em 24/11 ou 26/11 | 10 pts |
| 📊 Relatório e apresentação | Demonstração ao vivo em 10/12 | 10 pts |
NOTES.mdEm dupla de implementação é comum um escrever e o outro assistir. Na defesa oral, cada um por si.
| # | Data | Dia | Conteúdo |
|---|---|---|---|
| T0 | 01/09 | Ter | Apresentação. Anatomia de um SGBD |
| T1 | 03/09 | Qui | Armazenamento |
| — | 08 e 10/09 | CBSoft 2026, sem aula | |
| I1 | 15 e 17/09 | Laboratório M1. Entrega em 17/09 | |
| T2 | 22/09 | Ter | Cache de páginas |
| I2 | 24 e 29/09 | Laboratório M2. Entrega em 29/09 | |
| T3 | 01/10 | Qui | Árvore B+ |
| I3 | 06 e 08/10 | Laboratório M3. Entrega em 08/10 | |
| T4 | 13/10 | Ter | Parser e catálogo |
| I4 | 15 e 20/10 | Laboratório M4. Entrega em 20/10 | |
| T5 | 22/10 | Qui | Executor |
| I5 | 27 e 29/10 | Laboratório M5. Entrega em 29/10 |
| # | Data | Dia | Conteúdo |
|---|---|---|---|
| T6 | 03/11 | Ter | Transações |
| I6 | 05 e 10/11 | Laboratório M6. Entrega e sorteio dos seminários em 10/11 | |
| T7 | 12/11 | Qui | Recuperação |
| I7 | 17 e 19/11 | Laboratório M7. Entrega em 19/11 | |
| S1 | 24/11 | Ter | Seminários, primeira metade |
| S2 | 26/11 | Qui | Seminários, segunda metade |
| DO | 01 e 03/12 | Defesa oral individual | |
| — | 08/12 | Ter | Nossa Senhora da Conceição, sem aula |
| PF | 10/12 | Qui | Apresentações finais |
| — | 15, 17 e 22/12 | Buffer, fechamento e notas |
Um agente escreve uma árvore B+ em trinta segundos, e ela até passa nos testes.
NOTES.md não sai de código que vocês não entenderamO SELECT inteiro do minidb 0.0. Guardem esta função: vamos passar o semestre consertando ela.
# le_tudo() abre o arquivo e devolve TODAS as linhas if verbo == "SELECT": tabela = p[p.index("FROM") + 1] colunas = esquema.get(tabela, []) linhas = le_tudo() # o arquivo inteiro, sempre if "WHERE" in p: coluna, _, valor = p[p.index("WHERE") + 1 : ... ] indice = colunas.index(coluna) linhas = [l for l in linhas if l[indice] == valor] # imprime linha a linha, separado por |
$ 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 persiste em disco. É um banco de dados.
$ ls -lh big.db -rw-r--r-- 136M big.db $ time python3 hello.py big.db < consulta.sql 4999999|25259999|nome4999999 (1 linha) real 0m3,79s
Quase quatro segundos para achar uma linha. O PostgreSQL responde a mesma consulta em fração de milissegundo.
| Lê o arquivo inteiro a cada consulta | página e cache de páginas | M1 M2 |
| Percorre todas as linhas para achar uma | árvore B+ e varredura por índice | M3 M5 |
| O catálogo mora na memória e morre junto | catálogo em disco | M4 |
O parser é um split() e um pouco de fé | tokenizador e gramática | M4 |
| Escreve direto no arquivo, sem registro | log, COMMIT e ROLLBACK | M6 |
| Uma queda deixa metade do trabalho feito | log de escrita antecipada | M7 |
Na semana de 08 a 11/09 não haverá aula, por conta do CBSoft 2026. As entregas assíncronas vencem em 15/09.
Próxima aula: armazenamento, a página e o arquivo de dados