- LearnDB es un clon de SQLite y un sistema de gestión de bases de datos relacionales (RDBMS) implementado desde cero para comprender con mayor profundidad la estructura interna de las bases de datos
- Está escrito en Python puro, sin etapa de build, y por defecto funciona con cero configuración, aunque permite sobrescribir la configuración
- Ofrece learndb-sql, que soporta
select,from,where,group by,having,limityorder by, junto con un lexer y parser personalizados basados enlark - Está compuesto por un motor que recibe sentencias SQL y manipula las tablas y los datos de la base de datos, además de una estructura de datos de respaldo basada en btree en disco
- Se puede usar mediante REPL, importándolo como módulo de Python o pasando archivos de comandos al motor
- La base de código es adecuada para tinkering, pero tiene limitaciones importantes por las que no debe usarse como solución de almacenamiento real
- La aritmética de punto flotante es una implementación muy simplificada en comparación con IEEE754
- No soporta funciones utilitarias comunes, como la expansión de columnas con comodines tipo
select * ...
- Para ejecutarlo en desarrollo se requiere un sistema Linux/macOS y Python 3.9 o superior; usa
fcntlpara acceso de lectura exclusivo al archivo de base de datos - Usa como referencias el tutorial de bases de datos de cstack, SQLite Database System: Design and Implementation, la documentación del formato de archivos de SQLite y la documentación de PostgreSQL
1 comentarios
Opiniones de Hacker News
Creo que escribir este tipo de sistema en un lenguaje como Python es, de hecho, una excelente elección. Las bases de datos suelen escribirse en C++ o C, pero para mí Python es mucho más fácil de leer y más accesible.
Si se buscara rendimiento en serio, más adelante se podría portar a un lenguaje de bajo nivel, y en su forma actual es útil para aprender.
Yo también hice en Python una especie de base de datos distribuida multimodelo, que mezcla estilos SQL/grafo Cypher/documentos/DynamoDB, para aprender cómo puede funcionar un motor de base de datos en un entorno distribuido: https://GitHub.com/samsquire/hash-db
Tanto C como Python parecen accesibles si ignoras el mal diseño del lenguaje, las inconsistencias y las muchas trampas, y solo miras las partes fáciles. Pero con C al menos existe la posibilidad de aprender cómo hacerlo bien, mientras que con Python puede que ni siquiera llegues a saber cómo es el mundo real.
Hace muchísimo tiempo, alguien reescribió/portó SQLite de C a C#: https://code.google.com/archive/p/csharp-sqlite/wikis/Letter...
También vale la pena ver cuánto recibió con agrado ese trabajo el Dr. Richard Hipp.
Probablemente esté aquí en GitHub: https://github.com/CsharpDatabase/CsharpSQLite, y puede que haya más clones posteriores.
Excelente. Seguro fue una experiencia divertida y gratificante.
Sé que la intención no era hacerlo rápido, pero, por diversión, ¿se podrían crear también algunos benchmarks?
Gracias a este artículo descubrí Lark, una biblioteca de parser para Python que se ve bastante buena.
El tutorial de JSON del sitio es excelente. Primero muestra cómo crear un parser básico para JSON y luego cubre con bastante detalle cómo mejorar el rendimiento: https://lark-parser.readthedocs.io/en/latest/json_tutorial.h...
La gramática usada en el proyecto RDBMS está aquí: https://github.com/spandanb/learndb-py/blob/master/learndb/l...
El IDE fue muy útil para depurar la gramática: https://www.lark-parser.org/ide/
En EvaDB usamos Lark para un lenguaje similar a SQL orientado al uso de modelos de IA: https://github.com/georgia-tech-db/evadb/blob/master/evadb/p... https://github.com/georgia-tech-db/evadb/
Si te gusta Lark, vale la pena considerar patrocinarlo: https://github.com/sponsors/lark-parser
¿No sería mejor usar solo dicts con claves esperadas y composición mediante el operador OR bit a bit? Eso más o menos encaja con muchas formas gramaticales. Los imports podrían quedarse como imports, y quizá se podría mezclar todo de alguna manera.
Es mi primera impresión al verlo por encima, así que puede que se me esté escapando algo.
¿Hay partes que haya que seguir optimizando para que el parser generado sea más eficiente?
¿El siguiente paso lógico sería generar el plan de consulta óptimo a partir del AST?
Muy bueno.
SQLite es muy difícil de leer, pero esta implementación es bastante fácil de entender. En especial la parte de la máquina virtual: https://github.com/spandanb/learndb-py/blob/master/learndb/v...
Se puede comparar con este archivo: https://github.com/sqlite/sqlite/blob/master/src/vdbe.c
Aunque me da curiosidad qué tan completo es LearnDB. SQLite no es difícil de leer solo porque sea antiguo, sino también porque maneja muchas partes de SQL y se vuelve complejo al seguir la especificación de SQL.
SQLite tiene una excelente suite de pruebas, así que estaría bueno correr esas pruebas contra esta implementación.
Está realmente bueno y parece una buena forma para que alguien como yo aprenda mejor estructuras de datos y algoritmos. Puedo explicar cómo funciona un árbol B+, pero si me pidieran programarlo, creo que me quedaría trabado.
Me gustan las bases de datos y Python, así que fue realmente interesante revisarlo.
Además, el hecho de que sea una estructura almacenada en disco agregó otro factor de complejidad al pensar en la implementación.
¿Cuánto de la suite de pruebas de SQLite podría pasar?
¿Soporta garantías ACID o planificación/optimización de consultas?
No lo pregunto como si tuviera que hacerlo, sino porque quiero saber hasta dónde intentaste llegar además de los árboles B y SQL.
Yo también quisiera intentar algo así algún día. Gran trabajo.
Pero, fuera de eso, es una base de datos de un solo archivo, y solo una instancia de learndb puede ser el proceso que manipule el archivo de la base de datos. Así que, al ser una base de datos de una sola conexión, se obtiene consistencia y aislamiento.
La durabilidad se obtiene en la medida en que el sistema de archivos la proporcione. Así que queda en algún punto dentro de las propiedades ACID.
Todavía no implementé planificación/optimización de consultas, pero sí pensé dónde podría encajar un módulo de optimización. El parser emite un AST, y ese AST, o una representación intermedia derivada, se podría optimizar.
Es decir, antes de que la VM ejecute el AST, se podría reescribir el AST o eliminar nodos.
Un poco fuera de tema, pero ¿existe algo como mapDB para Python?
https://mapdb.org
Excelente proyecto. El código también es muy fácil de leer, y los comentarios son excelentes.