3 points par GN⁺ 2023-08-14 | 1 commentaires | Partager sur WhatsApp
  • LearnDB est un système de gestion de base de données relationnelle (RDBMS) et un clone de SQLite implémenté de zéro afin de mieux comprendre les structures internes des bases de données
  • Écrit en Python pur, sans étape de build, avec par défaut une configuration zéro et une architecture permettant de redéfinir les paramètres
  • Fournit learndb-sql, qui prend en charge select, from, where, group by, having, limit et order by, ainsi qu’un lexer et un parseur personnalisés basés sur lark
  • Se compose d’un moteur qui reçoit des instructions SQL pour manipuler les tables et les données de la base, et d’une structure de données de sauvegarde btree basée sur le disque
  • Modes d’utilisation pris en charge : REPL, import comme module Python, ou transmission d’un fichier de commandes au moteur
  • La base de code se prête bien au tinkering, mais comporte des limites essentielles qui interdisent de l’utiliser comme véritable solution de stockage
    • L’arithmétique en virgule flottante est implémentée de façon très simplifiée par rapport à IEEE754
    • Les fonctionnalités utilitaires courantes, comme l’expansion des colonnes avec un joker du type select * ..., ne sont pas prises en charge
  • Les prérequis d’exécution pour le développement sont un système Linux/macOS et Python 3.9 ou supérieur ; fcntl est utilisé pour l’accès exclusif en lecture aux fichiers de base de données
  • Les références utilisées incluent le tutoriel sur les bases de données de cstack, SQLite Database System: Design and Implementation, la documentation du format de fichier SQLite et la documentation PostgreSQL

1 commentaires

 
GN⁺ 2023-08-14
Avis de Hacker News
  • Je pense qu’écrire ce genre de système dans un langage comme Python est au contraire un excellent choix. Les bases de données sont généralement écrites en C++ ou en C, mais pour moi Python est bien plus lisible et accessible.
    Si l’on vise sérieusement les performances, on peut toujours porter le projet plus tard vers un langage bas niveau ; sous cette forme, il est utile pour l’apprentissage.
    Moi aussi, pour apprendre comment un moteur de base de données peut fonctionner en environnement distribué, j’ai créé en Python une sorte de base de données distribuée multimodèle mêlant SQL, graphes Cypher, documents et style DynamoDB : https://GitHub.com/samsquire/hash-db

    • C’est sans doute pour cela qu’il existe une communauté autour des bases de données relationnelles en Java pur. Des choses comme Hypersonic, H2 ou Derby : si l’on n’a pas besoin d’une échelle de niveau gros systèmes, elles sont faciles à déployer et à utiliser, et aussi faciles à intégrer en mémoire si nécessaire.
    • Tout à fait d’accord. Dans le même esprit, la série ugit, qui crée Git à partir de zéro en Python, était vraiment excellente : https://www.leshenko.net/p/ugit/
    • Je ne sais pas trop. Python est aussi mauvais que C/C++, mais il a l’inconvénient que, si l’on veut apprendre à créer une base de données, on ne peut pas vraiment toucher à beaucoup des parties intéressantes qu’il faudrait explorer.
      C comme Python paraissent accessibles si l’on ignore leur mauvaise conception de langage, leurs incohérences et leurs nombreux pièges pour ne regarder que les parties faciles. Mais avec C, on a au moins une chance d’apprendre comment faire les choses correctement ; avec Python, on risque même de ne pas savoir à quoi ressemble le monde réel.
    • Beau travail. J’ai ressenti quelque chose de similaire, et Python m’a permis de me concentrer sur les concepts de haut niveau. Cela dit, il y a aussi eu des moments où je me suis dit que j’aurais aimé le faire avec un langage à typage statique et compilé.
  • Il y a très longtemps, quelqu’un avait réécrit/porté SQLite de C vers C# : https://code.google.com/archive/p/csharp-sqlite/wikis/Letter...
    Cela vaut le coup de voir à quel point le Dr Richard Hipp a accueilli favorablement ce travail.
    Il semble que le dépôt GitHub soit ici : https://github.com/CsharpDatabase/CsharpSQLite et il peut aussi exister d’autres clones depuis.

  • Excellent. Cela a clairement dû être une expérience amusante et enrichissante.
    Je sais que l’objectif n’était pas d’aller vite, mais, pour le plaisir, serait-il possible de créer quelques benchmarks ?

    • Un peu hors sujet, mais connaissez-vous de bonnes ressources, conférences ou billets de blog sur la manière d’écrire des benchmarks utiles ?
    • Implémenter quelque chose comme TPC-C dans learndb et voir ce que ça donne pourrait aussi être un exercice amusant.
  • Grâce à cet article, j’ai découvert Lark, une bibliothèque de parsing pour Python qui a l’air plutôt bonne.
    Le tutoriel JSON du site est excellent. Il montre comment créer un parseur de base pour JSON, puis explique assez en détail comment en améliorer les performances : https://lark-parser.readthedocs.io/en/latest/json_tutorial.h...
    La grammaire utilisée dans le projet RDBMS se trouve ici : https://github.com/spandanb/learndb-py/blob/master/learndb/l...

    • Je recommande vivement Lark pour les projets Python. C’est facile à utiliser.
      L’IDE m’a été très utile pour déboguer la grammaire : https://www.lark-parser.org/ide/
      Dans EvaDB, nous utilisons Lark pour un langage de type SQL adapté à l’utilisation de modèles d’IA : https://github.com/georgia-tech-db/evadb/blob/master/evadb/p... https://github.com/georgia-tech-db/evadb/
      Si vous aimez Lark, cela vaut aussi la peine d’envisager de le sponsoriser : https://github.com/sponsors/lark-parser
    • Un DSL dans une chaîne de caractères, vraiment, est-ce une bonne approche ? Je ne me souviens pas avoir déjà utilisé ça en Python ni en avoir eu besoin, mais j’ai l’impression qu’il doit être possible de faire mieux.
      Rien qu’avec des dict ayant les clés attendues et une composition via l’opérateur OR bit à bit, on pourrait peut-être mieux coller à beaucoup de formes grammaticales. Les import pourraient rester des import, et on pourrait sans doute mélanger tout ça d’une manière ou d’une autre.
      C’est juste ma première impression en y jetant un coup d’œil, donc j’ai peut-être raté quelque chose.
    • Sans vouloir paraître impoli, je reconnais que ce travail est excellent et que c’est une façon d’apprendre de nouvelles choses. Mais si la génération de parseur n’est pas l’objectif final, seulement un moyen pour exécuter l’AST dans la base de données, je me demande ce que l’on apprend précisément avec la partie parseur.
      Y a-t-il des aspects qu’il faut continuer à optimiser pour rendre le parseur généré plus efficace ?
      L’étape logique suivante serait-elle de produire, à partir de l’AST, le plan de requête optimal ?
  • Très bien
    SQLite est très difficile à lire, mais cette implémentation est assez facile à comprendre. C’est particulièrement vrai pour la partie machine virtuelle : https://github.com/spandanb/learndb-py/blob/master/learndb/v...
    On peut la comparer avec ce fichier : https://github.com/sqlite/sqlite/blob/master/src/vdbe.c
    Je me demande toutefois à quel point LearnDB est complet. SQLite n’est pas difficile à lire seulement parce qu’il est ancien, mais aussi parce qu’il couvre une grande partie de SQL et devient complexe en suivant la spécification SQL
    SQLite dispose d’une excellente suite de tests, donc ce serait intéressant de les faire tourner sur cette implémentation

  • Vraiment bien, et ça semble être une bonne manière pour quelqu’un comme moi de mieux apprendre les structures de données et les algorithmes. Je peux expliquer comment fonctionne un B+tree, mais si on me demandait de le coder moi-même, je pense que je bloquerais
    Comme j’aime les bases de données et Python, parcourir le projet a été vraiment intéressant

    • Absolument. L’implémentation du B-tree a été la motivation initiale pour lancer ce projet. Les détails liés au rééquilibrage et à la division des nœuds étaient particulièrement importants
      En plus, le fait que la structure soit stockée sur disque ajoutait une couche de complexité supplémentaire au moment de réfléchir à l’implémentation
  • Quelle part de la suite de tests SQLite pourrait-il réussir ?

  • Est-ce que ça prend en charge les garanties ACID ou la planification/l’optimisation de requêtes ?
    Je ne demande pas ça en sous-entendant que ça devrait forcément le faire ; je voudrais juste savoir jusqu’où tu es allé au-delà des B-tree et de SQL
    J’aimerais essayer quelque chose comme ça un jour. Beau travail

    • Concernant les garanties ACID, il n’y a pas de notion permettant de regrouper plusieurs instructions de façon atomique, c’est-à-dire pas de transactions
      Mais pour le reste, c’est une base de données dans un fichier unique, et un seul processus, une seule instance de learndb, peut manipuler le fichier de base de données. On obtient donc cohérence et isolation dans le cadre d’une base à connexion unique
      La durabilité est assurée dans la mesure où le système de fichiers fournit cette durabilité. On se situe donc quelque part sur le spectre des propriétés ACID
      La planification/l’optimisation de requêtes n’est pas encore implémentée, mais j’ai réfléchi à l’endroit où un module d’optimisation pourrait s’insérer. Le parseur produit un AST, et cet AST, ou une représentation intermédiaire dérivée, pourrait être optimisé
      Autrement dit, avant que la VM n’exécute l’AST, on pourrait réécrire l’AST ou supprimer des nœuds
  • Un peu hors sujet, mais existe-t-il en Python quelque chose comme mapDB ?
    https://mapdb.org

  • Excellent projet. Le code est aussi très lisible, et les commentaires sont excellents