SQLite Primer
SQLite is the most widely deployed database engine on the planet, embedded in every phone, browser, and countless desktop apps. This primer walks you through opening a database, running queries, and shaping schemas for production use inside a Meridian project.
01.Opening a database
A SQLite database is a single file on disk. Opening it is as simple as pointing the driver at a path. If the file does not exist, SQLite creates it for you on the first connection. Use WAL mode for concurrent reads and writes in production workloads.
import Database from 'better-sqlite3'
const db = new Database('meridian.db')
db.pragma('journal_mode = WAL')
db.pragma('foreign_keys = ON')02.Designing a schema
SQLite is dynamically typed, but you should still declare column types for clarity and to take advantage of type affinity. Use INTEGER PRIMARY KEY for rowid aliases, and lean on CHECK constraints to keep data clean at the storage layer.
- Prefer
TEXToverVARCHAR(n). - Store timestamps as ISO-8601 strings or unix epoch integers.
- Index foreign keys explicitly; SQLite does not do it for you.
03.Querying safely
Always use prepared statements with bound parameters. Never concatenate user input into SQL strings. The driver caches prepared statements, which means repeated queries are also dramatically faster than ad-hoc string building.
const insert = db.prepare(
'INSERT INTO users (email, created_at) VALUES (?, ?)'
)
const row = insert.run('founder@example.com', Date.now())
const get = db.prepare('SELECT * FROM users WHERE id = ?')
const user = get.get(row.lastInsertRowid)