不想再挂 Postgres / MySQL 时,常用嵌入式(进程内)数据库。按 SQL 和 KV 分开看。
SQL:SQLite
需要表、JOIN、索引、迁移工具、ORM 时,几乎都是 SQLite。差别主要在 Go 驱动。
| 驱动 | CGO | 类型 | 核心亮点 | 主要短板 | 适合 |
|---|---|---|---|---|---|
| mattn/go-sqlite3 | 要 | database/sql | 生态默认、吞吐通常最高 | 交叉编译 / Alpine / CI 麻烦 | 能接受 CGO、要极致性能 |
| modernc.org/sqlite | 不要 | database/sql | 纯 Go、好交叉编译 | 写密集场景往往略慢于 mattn | 部署要简单、纯 Go 构建 |
| ncruces/go-sqlite3 | 不要 | database/sql | WASM 版 SQLite | 额外运行时开销 | 要纯 Go 又想跟官方 SQLite 行为更近 |
| crawshaw / zombiezen 等 | 视实现 | 非 database/sql 或轻量 API | 更贴近 C API、可控 | 和 GORM 等生态摩擦大 | 要细控 SQLite、不绑 database/sql |
实务上:能忍 CGO 用 mattn;要 GOOS/GOARCH 随便交叉、容器构建省心用 modernc。
KV:纯 Go 嵌入式
只要 key → value、自己管序列化 / 索引时,KV 更轻。
| 库 | 结构 | 纯 Go | 事务 | 核心亮点 | 主要短板 | 适合 |
|---|---|---|---|---|---|---|
| bbolt(etcd-io) | B+ tree | 是 | ACID,单写多读 | API 简单、单文件、读友好、内存稳 | 写吞吐一般 | 元数据、配置、读多写少;默认首选 |
| BoltDB | B+ tree | 是 | 同左 | 历史经典 | 已停更,应迁到 bbolt | 遗留代码 |
| Badger | LSM + value log | 是 | ACID(SSI) | 写快、SSD 友好、TTL、版本 | 多文件、内存更高 | 写多、大 value、服务端 |
| Pebble | LSM | 是 | 快照 / batch | CockroachDB 同款引擎、写与 range 强 | API / 运维比 bbolt 重 | 要 RocksDB 级 LSM、又想纯 Go |
| goleveldb | LSM | 是 | 基础 | LevelDB 纯 Go 移植、依赖少 | 不如 Badger/Pebble 活跃 | 轻量 LSM、老项目 |
| NutsDB | Bitcask / 类 LSM | 是 | 支持 | 功能多(list/set/zset 等) | 社区与生产案例少于前几名 | 想要类 Redis 数据结构 |
| Buntdb | 内存 + 持久化选项 | 是 | 支持 | 内存索引、可按 index 查 | 数据主要在内存 | 小数据、热数据、带索引查询 |
粗分:读多、省心 → bbolt;写多、量大 → Badger / Pebble。
怎么选
| 需求 | 建议 |
|---|---|
| 要 SQL / ORM / 复杂查询 | SQLite(mattn 或 modernc) |
| 通用 KV、读多、省心 | bbolt |
| 高写入、大 value、TTL | Badger |
| 要接近 RocksDB 的 LSM、纯 Go | Pebble |
| 内存为主、带二次索引 | Buntdb |
| 想要嵌入式里的「小 Redis」 | 可看 NutsDB,先评估成熟度 |
| Bolt 遗留代码 | 迁到 bbolt(go.etcd.io/bbolt) |
注意
- 嵌入式库一般是 单进程打开;多进程同时写同一个库文件容易出问题,SQLite 多进程读相对好一些,但仍不如独立数据库服务。
- 写入耐久性(
fsync/ WAL)会影响吞吐,对比 benchmark 时要看是否同档 durability。 - Bolt 时代的代码用 bbolt,包路径换成
go.etcd.io/bbolt即可。 - 选 SQLite 驱动时,先确认 GORM / sqlc / migrate 是否已验证过该驱动。
推荐(一句话)
要查询 → SQLite + modernc(部署优先)或 mattn(性能优先);默认 KV → bbolt;写密集 → Badger;Cockroach 同款存储层 → Pebble。