Skip to content

Latest commit

 

History

History
101 lines (57 loc) · 2.8 KB

README.md

File metadata and controls

101 lines (57 loc) · 2.8 KB

Stupid Database

This is an exercise in building a very minimal (and very stupid) in-memory SQL-like database for educational purposes.

None of this code is to be considered usable in a real project. There are no safeguards, security, checks, or anything that resembles production-ready code. And it's written this way to be easily understandable for a very beginner programmer.

The goal is to demystify the SQL syntax like:

SELECT name FROM users WHERE age > 30

To an equivalent javascript call like:

select('name', from('users', { where: 'users.age > 30' }))

And the idea is to have a "mental model" of what SQL means in a more general programming language

You can run the example with:

node test

REPL

You can open an interactive REPL to run SQL command directly by running:

./repl.js

It's a node REPL and you can send SQL commands like this:

stupid sql > select name from users where users.city = 'Gotham'

REPL with Transaction Log

This is another experimental version of a persistency layer based on a simple append-only transaction log.

This will decorate the insert, delete and update functions with special transaction-enabled versions.

Transactions will be saved in the 'transact.log' file.

Run: ./replTransact.mjs

This will replay existing transactions and save new operations to the transaction log.

Client/Server

There is also a demonstration of the most minimal bare-bones "SQL-like" database. You can start this server at port 4000:

./stupid-server.mjs

And connect to it with this client:

./stupid-client.mjs

It will open an interactive prompt so you can send the SQL commands

AVL Tree based Index

Just to show how an index is built and used (in a normal SQL server, it's obviously a B+Tree, but as this is a stupid in-memory hash, a simple AVL Tree should suffice).

We can compare the times for the equivalente of a 'table scan' filtering every single element in the table or using the index.

./bench_index.mjs

Spoilers: on my i9-9900K, with NVME, running inside WSL2, this is the result:

` ❯ ./bench_index.mjs from('users', { where: 'users.city === "Wakanda"'}).length took 145 ms normal select: 524288

getFromIds(users,getFromIndex('users', 'city', 'Wakanda')).length took 20 ms indexed select: 524288 `

The AVL indexed version can go from anywhere around 5 to 10 times faster, obviously.

ANTLR4

Just out of fun, I did a very small and very naive implementation of a SQL parser using Antlr4.

You can run very basic SQL against the stupid database. Just add the commands in the test.sql file and run doing:

./stupid.mjs

The parser is a stripped down version copied from the SQLite3 parser.

Again, this is for educational purposes only.


Copyright (C) Fabio Akita, 2022 This project should not be used out of context, without the permission of the author