Índice

Construyendo una base de datos — nyx-db

Que es nyx-db?

nyx-db es un motor de base de datos SQL embebido escrito completamente en Nyx. Acepta comandos SQL sobre el protocolo RESP (igual que nyx-kv), asi que puedes usar redis-cli como cliente. Piensa en el como un mini SQLite accesible por red.

Arquitectura

SQL string ──► Lexer ──► Parser ──► AST ──► Executor ──► Storage
                                                            │
                                                         ┌──┴──┐
                                                         │.db  │
                                                         │file │
                                                         └─────┘

El pipeline tiene cuatro etapas:

  1. Lexer — tokeniza la cadena SQL en palabras clave, identificadores, literales y operadores.
  2. Parser — parser de descenso recursivo que construye un AST (arbol de sintaxis abstracta).
  3. Executor — recorre el AST y ejecuta la operacion solicitada.
  4. Storage — las filas se almacenan en memoria en Maps, con persistencia en segundo plano a un archivo .db.

Conectar

nyx-db escucha en el puerto 6382 por defecto:

$ redis-cli -p 6382
127.0.0.1:6382> PING
PONG

Crear tablas

127.0.0.1:6382> SQL CREATE TABLE users (id INT PRIMARY KEY, name TEXT, age INT)
OK

Tipos soportados: INT, TEXT, REAL. La restriccion PRIMARY KEY garantiza unicidad.

Insertar datos

127.0.0.1:6382> SQL INSERT INTO users VALUES (1, 'Alice', 30)
OK
127.0.0.1:6382> SQL INSERT INTO users VALUES (2, 'Bob', 25)
OK
127.0.0.1:6382> SQL INSERT INTO users VALUES (3, 'Charlie', 35)
OK

Consultar datos

127.0.0.1:6382> SQL SELECT * FROM users
1) "id=1, name=Alice, age=30"
2) "id=2, name=Bob, age=25"
3) "id=3, name=Charlie, age=35"

Selecciona columnas especificas con una clausula WHERE:

127.0.0.1:6382> SQL SELECT name, age FROM users WHERE age > 28
1) "name=Alice, age=30"
2) "name=Charlie, age=35"

Ordenar y limitar resultados:

127.0.0.1:6382> SQL SELECT * FROM users ORDER BY age DESC LIMIT 2
1) "id=3, name=Charlie, age=35"
2) "id=1, name=Alice, age=30"

Funciones de agregacion:

127.0.0.1:6382> SQL SELECT COUNT(*) FROM users
(integer) 3

Actualizar y eliminar

127.0.0.1:6382> SQL UPDATE users SET age = 31 WHERE name = 'Alice'
OK (1 row updated)

127.0.0.1:6382> SQL DELETE FROM users WHERE age < 30
OK (1 row deleted)

Indices

Crea un indice para acelerar consultas en columnas buscadas frecuentemente:

127.0.0.1:6382> SQL CREATE INDEX idx_age ON users (age)
OK

Transacciones

Agrupa multiples operaciones en una transaccion atomica:

127.0.0.1:6382> SQL BEGIN
OK
127.0.0.1:6382> SQL INSERT INTO users VALUES (4, 'Diana', 28)
OK
127.0.0.1:6382> SQL INSERT INTO users VALUES (5, 'Eve', 22)
OK
127.0.0.1:6382> SQL COMMIT
OK

Usa ROLLBACK para deshacer todos los cambios desde BEGIN.

Meta comandos

ComandoDescripcion
TABLESLista todas las tablas
SCHEMA tablenameMuestra el esquema de la tabla (columnas y tipos)
INFOEstadisticas del servidor
PINGVerificacion de salud

Persistencia

nyx-db persiste datos en un archivo .db. Un hilo de guardado en segundo plano escribe snapshots periodicamente, y un handler de cierre asegura un guardado final en SIGTERM. Al reiniciar, todas las tablas y filas se restauran desde disco.

$ ./nyx-db --data mydata.db --port 6383

El parser SQL

El parser es un clasico parser de descenso recursivo. Lee tokens de uno en uno y construye nodos del AST. Por ejemplo, parsear SELECT * FROM users WHERE age > 25 produce:

["SELECT",                    ← tipo de nodo
  ["*"],                      ← columnas
  "users",                    ← nombre de tabla
  [">", "age", 25],           ← expresion WHERE
  [],                         ← ORDER BY (vacio)
  -1,                         ← LIMIT (ninguno)
  0,                          ← OFFSET
  []]                         ← JOIN (vacio)

Las expresiones WHERE soportan AND, OR y operadores de comparacion (=, !=, <, >, <=, >=) con la precedencia correcta.

Resumen

← Anterior: HTTP/2 — Protocolos binarios Siguiente: Apéndice A: Referencia rápida de sintaxis →