A SQLite-inspired embedded database built from scratch in Odin to learn database internals, storage engines, query execution, and systems programming.
The goal of this project is learning, not production readiness. Every subsystem is implemented incrementally to understand why modern databases are designed the way they are.
- Learn database internals from first principles
- Build a single-node embedded database
- Store data directly on disk
- Implement page-oriented storage
- Progressively evolve toward a SQLite-like architecture
Implemented a simple binary row format.
Features:
- Binary serialization/deserialization
- Persistent storage in a
.binfile - Insert rows
- Read all rows
- Sequential full table scan
- Find row by ID
- Count rows
Refactored storage from an append-only file into fixed-size pages.
Features:
- Fixed-size pages (4 KB)
- Page allocation
- Multiple page support
- Page header
- Rows stored inside pages
- Page offset calculation
- Page persistence
Introduced a pager abstraction responsible for all disk I/O.
Responsibilities:
- Create pages
- Read pages
- Write pages
- Count pages
- Allocate new pages
The pager is the only component that interacts directly with the database file. Higher-level components work exclusively with pages.
Refactored page layout to support variable-length records and stable record references.
Features:
- Self-describing page header
- Slot directory
- Free-space management
- Rows grow from the end of the page
- Slots grow from the beginning of the page
- Stable slot-based record references
- Separation between physical row location and logical record identity
- Deletion & free-space reuse
- Page compaction
- Page cache / buffer pool
- Table abstraction
- B-Tree storage
- SQL parser
- Query execution engine
- Transactions
- Write-Ahead Logging (WAL)
- Basic query optimization
db/
└── storage/
├── pager/
│ ├── pager.odin
│ ├── page.odin
│ └── page_header.odin
└── ...
The project structure will continue evolving as new storage engine components are introduced.
This project intentionally avoids copying SQLite's implementation.
Instead, every subsystem is designed from first principles to understand:
- Why pages exist
- Why slotted pages exist
- Why B-Trees are used
- How records are stored
- How databases interact with disk
- How storage engines are architected
The focus is on developing intuition and understanding the trade-offs behind real database systems rather than reproducing SQLite's source code.