Files
rdbms-playground/docs/adr/0002-database-engine.md
T
claude@clouddev1 3a0c03d781 Initial planning docs: CLAUDE.md and ADRs 0000-0008
Captures up-front design decisions for RDBMS Playground:
stack (Rust + Ratatui + SQLite), input modes, project file
format, type vocabulary, undo snapshots and replay log,
sharing/export, and testing approach. ADR-0000 establishes
the ADR practice itself and mandates index upkeep alongside
any ADR change.
2026-05-07 09:27:31 +00:00

2.0 KiB

ADR-0002: Database engine

Status

Accepted

Context

The application teaches relational database concepts. Requirements on the engine:

  • File-based, with a single binary file that can live in the project folder.
  • Real RDBMS feature set: typed columns, primary keys, foreign keys with referential integrity, indexes, query planner output we can expose to learners.
  • Industry adoption — students should leave with a skill that maps to something they will encounter again.
  • Embeddable from Rust without arcane build steps.

Candidates considered:

  • SQLite — file-based, near-universal adoption, supports FK enforcement, has EXPLAIN QUERY PLAN, and since 3.37 supports STRICT tables which give proper type enforcement instead of SQLite's traditional loose type affinity.
  • DuckDB — file-based, modern, but analytical/columnar by design; would teach analytical instincts that mislead in transactional contexts.
  • Embedded Postgres (pglite, pg_embed) — closest to a "real" RDBMS, but adds friction and complicates packaging.

Decision

Use SQLite via the rusqlite crate. All tables are created as STRICT tables. Foreign-key enforcement is enabled per-connection (PRAGMA foreign_keys = ON).

Simplified user-facing column types (see ADR-0005) are mapped to the underlying SQLite STRICT types at parse time.

Consequences

  • Tight, low-friction packaging — rusqlite bundles SQLite.
  • EXPLAIN QUERY PLAN output is directly usable for the query analysis feature (ADR pending).
  • SQLite's ALTER TABLE is limited (e.g. type changes, some drops). Schema evolution will use the rebuild-table technique internally; this is hidden from users in simple mode and exposed honestly in advanced mode.
  • STRICT tables forbid the historical permissive typing students might encounter elsewhere — this is intentional and matches the pedagogical goal.
  • Booleans are stored as INTEGER (0/1) per SQLite's STRICT type set; the bool user-facing type maps to this and is rendered as true/false in result views.