KeiSeiKit-1.0/_blocks/db-sqlite.md
Parfii-bot f884891862 feat(blocks): 5 database blocks — postgres/sqlite/sqlx/drizzle/migration-hygiene
- db-postgres.md: PG17 patterns (indexes, pooling, backup); [E4]
- db-sqlite.md: WAL prod patterns, Turso/LiteFS/D1, FTS5
- db-sqlx.md: Rust compile-time checked queries, offline mode
- db-drizzle.md: TS schema-first, drizzle-kit migrations
- db-migration-hygiene.md: universal up/down, zero-downtime,
  backfill, checksum tracking

All blocks <60 LOC per Constructor Pattern. Version numbers
marked [UNVERIFIED] where exact minor pins are needed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 20:31:37 +08:00

34 lines
2.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# DB — SQLite (prod-suitable) patterns
Use when the workload is read-heavy, single-writer-acceptable, or needs zero-ops embedded storage. SQLite is prod-suitable — Fly.io, Turso, Cloudflare D1, and countless CLI/mobile apps run it in production. [E4 — expert assessment]
**When NOT to use:** high-concurrency write workload (> ~1 writer/sec sustained), multi-region strong consistency, horizontal write scaling. Use Postgres instead.
**WAL mode is mandatory for prod:**
```sql
PRAGMA journal_mode = WAL; -- readers don't block writer, writer doesn't block readers
PRAGMA synchronous = NORMAL; -- durable across app crash, NOT across power loss (use FULL if PSU-risk)
PRAGMA busy_timeout = 5000; -- 5s wait for lock instead of instant SQLITE_BUSY
PRAGMA foreign_keys = ON; -- default OFF in SQLite (!), always enable
PRAGMA temp_store = MEMORY;
```
Apply these on every connection open — they are per-connection, not per-database (except `journal_mode` which persists).
**Distributed patterns:**
- **Turso** (libSQL fork): edge-replicated read replicas with HTTP/WebSocket wire protocol. Primary single-writer, replicas read-only. [E4]
- **LiteFS** (Fly.io): file-system replication, leader-election via Consul. Primary+replicas. [E4]
- **Cloudflare D1**: managed SQLite on edge with their own replication. [UNVERIFIED: current throughput limits]
- **Litestream**: continuous replication to S3/R2 for backup + PITR; single node, not HA.
**Full-text search (FTS5):**
```sql
CREATE VIRTUAL TABLE docs_fts USING fts5(title, body, content=docs, content_rowid=id);
CREATE TRIGGER docs_ai AFTER INSERT ON docs BEGIN
INSERT INTO docs_fts(rowid, title, body) VALUES (new.id, new.title, new.body);
END;
```
FTS5 outperforms bolt-on `LIKE '%x%'` by 100×+ on large text corpora. Native, no extension install.
**Backup:** `sqlite3 db '.backup /path/backup.db'` while app runs (safe with WAL). Or Litestream for continuous.
**Forbidden:** multiple writer processes without a coordination layer; opening the same DB over NFS (lock semantics broken); `DELETE FROM bigtable` without `VACUUM` after (doesn't shrink file); committing the `.db` / `.db-wal` / `.db-shm` files to git.