MiniDB es un proyecto didáctico escrito en C++ moderno que implementa un motor de base de datos embebido con tablas de ancho fijo, índices B-Tree en disco y un mini intérprete SQL. Incluye además un cliente CLI y un Workbench GUI (Qt 6) con editor SQL, resultados tabulares y explorador de carpetas.
Objetivo: demostrar dominio práctico de C++ (I/O binario, estructuras en disco, B-Trees, modelos Qt, CMake) construyendo un stack BD completo y funcional.
-
Tablas de registros de ancho fijo persistidas en archivos
.tbl. -
Tipos soportados:
INT/INTEGER(32-bit),FLOAT/REAL(32-bit),CHAR(n)(fijo). -
Esquema auto-contenido al inicio del archivo (cabecera + metadatos de columnas).
-
Columna
id INTautoincremental agregada por defecto enCREATE TABLE. -
Borrado lógico por
pageIDmarcandoid = -1. -
Índices en disco (B-Tree) por columna:
*.btiparaINT,*.btfparaFLOAT,*.btsparaCHAR(32).- Búsqueda exacta y por rango; duplicados permitidos (multi-valor por clave).
-
Intérprete SQL con soporte para:
-
CREATE DATABASE,USE,CLOSE,SHOW TABLES -
CREATE TABLE,CREATE INDEX -
INSERT INTO … VALUES (…) -
SELECT … FROM … [WHERE …]con operadores==,!=,<=,>=,<,>- Usa índice si existe; cae a escaneo secuencial si no.
-
DELETE FROM … [WHERE …](borrado lógico; sincroniza índices) -
UPDATE … SET … [WHERE …](actualiza archivo, reindexa columnas afectadas)
-
-
Estrategias para mantener índices frescos tras
INSERT/DELETE/UPDATE.
-
Mini-Workbench:
- Árbol de archivos (QFileSystemModel + QTreeView).
- Editor SQL con resaltado (QPlainTextEdit +
SqlHighlighter). - Consola integrada (historial + ejecución).
- Resultados
SELECTen tabla (QTableView +QAbstractTableModelpropio). - Botones/acciones: Crear BD, Crear Tabla, Ejecutar, Abrir Terminal.
- Renderizado de SELECT filtrando filas borradas lógicamente (
id == -1).
-
Terminal externa opcional: lanza
demo_clidesde el Workbench (Windows/macOS/Linux).
MiniDB/
├─ engine/
│ ├─ GenericFixedTable.h # Tabla de ancho fijo (I/O en disco).
│ ├─ DiskBTreeMulti.h # B-Tree genérico en disco (int/float/char).
│ ├─ MiniDatabase.h # Orquestador: DB, tablas, índices.
│ └─ MiniDBSQL.h # Intérprete/ejecutor SQL.
│
├─ cli/
│ ├─ MiniDBCLI.h # CLI simple (REPL).
│
├─ gui/ (Qt 6)
│ ├─ mainwindow.h/.cpp # QMainWindow + toolbar + docks.
│ ├─ resulttablemodel.h/.cpp # Modelo de resultados para QTableView.
│ ├─ consolewidget.* # Consola (historial + prompt).
│ ├─ sqlhighlighter.* # Resaltado de sintaxis básico.
│ └─ MiniDBWorkbench.pro / CMakeLists.txt
│
└─ CMakeLists.txt # Build principal
Nota: algunos nombres pueden variar según tu árbol; el README refleja los archivos reales utilizados:
GenericFixedTable.h,DiskBTreeMulti.h,MiniDatabase.h,MiniDBSQL.h,mainwindow.cpp,resulttablemodel.cpp,main_cli_demo.cpp, etc.
- Cabecera
FileHeader+ metadatos de columnasColMetaDisk(packed,#pragma pack(push,1)). - Cada fila se serializa/deserializa con
pack_row/unpack_row. - API por
pageID:AppendRow,ReadRowByPageID,WriteRowInDisk,Count. - Getters por nombre de columna (
ReadInt/Float/Char). - Borrado lógico: la fila se considera “borrada” si su campo
idvale-1. (El Workbench y el executor filtran esas filas paraSELECT.)
- Plantilla parametrizada por traits (
KeyInt,KeyFloat,KeyChar32). - Nodos en disco
NodeDiskGeneric<KEY_BYTES>con fanout configurable. - Operaciones:
insert,search_get_value,range_search_values,remove_key. - Archivos con cabecera
FileHeaderpropia (MAGIC por tipo y metadatos de nodo).
- Gestiona directorio raíz de la BD (
CREATE/USE/CLOSE). - Crea/abre tablas (
GenericFixedTable) y construye índices por columna. - Mantiene y reutiliza índices abiertos en la sesión.
- Exposición de búsquedas indexadas (
buscar_unitaria,buscar_rango) y hooks de mantenimiento trasINSERT/DELETE/UPDATE.
- Parser ligero por slicing de strings:
trim,to_upper,split_csv. TableSchemase rellena leyendo del archivo.tbl(no hay metastore aparte).CREATE TABLE: inserta siempreid INTal frente.INSERT: autoincrementaidsi no fue provisto (basado enCount()+1).SELECT: proyección, WHERE (==,!=,<=,>=,<,>) conAND/OR. Usa índice si existe, luego filtra exacto por tipos.DELETE FROM: resuelveWHERE, marca filas como borradas (id=-1) y actualiza índices.UPDATE: aplicaSET(int/float/char), reescribe fila en disco y reindexa las columnas afectadas.
- CMake ≥ 3.20
- Qt 6.x (Widgets, Core, Gui)
- Compilador C++17 (GCC/Clang/MSVC o MinGW 64-bit en Windows)
git clone <repo>
cd MiniDB
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -jEsto genera, entre otros, demo_cli (o demo_cli.exe en Windows).
Con CMake (recomendado):
cmake -S gui -B build-gui -DCMAKE_PREFIX_PATH="<ruta a Qt6>"
cmake --build build-gui -jEn Windows (MinGW), compila demo_cli y el Workbench con el mismo kit para evitar problemas de DLL.
./demo_cli
MiniDB SQL Console
help
- Abre la app.
- Usa el árbol de archivos para navegar a la carpeta DB, o crea una con Crear BD.
- Escribe comandos en el editor y pulsa Ejecutar.
- Abre la Terminal para lanzar
demo_clidirectamente (la app ajusta elPATHa las DLL de Qt/MinGW).
-- Crear base y tabla
CREATE DATABASE mi_db
USE mi_db
CREATE TABLE ventas (cliente INT, total FLOAT, producto CHAR(32))
-- Insertar (id autoincrementa)
INSERT INTO ventas (cliente,total,producto) VALUES (40, 85.12, 'ANA')
INSERT INTO ventas (cliente,total,producto) VALUES (41, 8127, 'JUAN')
-- Índice por id (se crea automático al primer SELECT *, o explícito)
CREATE INDEX idx_ventas_id ON ventas (id)
-- Consultas
SELECT * FROM ventas
SELECT cliente,total FROM ventas WHERE total >= 100 AND total < 1000
SELECT * FROM ventas WHERE producto != 'ANA'
-- Actualizar
UPDATE ventas SET total = 293.12 WHERE cliente == 44
UPDATE ventas SET producto = 'UPDATED' WHERE producto == 'OK'
-- Borrado lógico
DELETE FROM ventas WHERE id == 9- INSERT: después de persistir la fila nueva, se insertan las claves de columnas indexadas (incluida
id) con supageID. - DELETE: tras marcar
id = -1, se remueven del índice todas las columnas indexadas para esepageID. - UPDATE: para cada columna afectada por
SETque esté indexada, se elimina la clave vieja y se inserta la nueva (mismapageID).
El Workbench y el executor filtran en memoria cualquier fila con
id == -1para que no aparezca enSELECT.
- No hay
NULLni tipos compuestos. CHAR(n)es ancho fijo en disco (relleno con\0),KeyChar32indexa a 32 bytes (se trunca/pad).- El parser SQL es minimalista (sin comillas dobles, sin escapes complejos).
- No hay control de concurrencia; pensado para uso embebido/monoproceso.
- No hay vacuum/compactación física (el borrado es lógico).
-
En Windows: si la Terminal del Workbench no arranca
demo_cli.exe, asegúrate de:- Compilar con el mismo kit (Qt 6.x MinGW 64-bit).
- Tener
demo_cli.exejunto al ejecutable del Workbench (misma carpetabuild\...\Debug\oRelease). - La función
onOpenTerminal()ajusta elPATHen tiempo de ejecución para que el proceso encuentre las DLL.
-
Ves filas borradas en la GUI: confirma que estás usando las versiones de
mainwindow.cppyresulttablemodel.cppque filtranid == -1.
ALTER TABLEbásico (añadir columna al final).ORDER BYyLIMIT.VACUUMpara compactar y reciclarpageIDde filas borradas.- Índices compuestos y UNIQUE.
- Tests automatizados (GoogleTest) para B-Tree, Insert/Update/Delete/Select.
- Haz un fork & crea una rama.
- Respeta el estilo (C++17, warnings altos,
-Wall -Wextra). - Incluye pruebas o casos reproducibles en PRs.
Proyecto de demostración de conocimientos sólidos en C++ (memoria, archivos binarios, estructuras de datos, Qt). Contact: ja2958110@gmail.com / https://www.linkedin.com/in/jesus-arturo-arias-lopez-9b82902aa/ / https://skeletus.github.io/.
Si te interesa profundizar en alguna capa (B-Tree, pack/unpack, o el modelo Qt), avísame y documento esa sección con diagramas y pseudocódigo.