结论:用 github.com/mattn/go-sqlite3 是当前最稳妥的本地 sqlite 方案,但必须配 c 编译环境;若想免 cgo、跨平台一键编译,就选 github.com/glebarez/go-sqlite(纯 go 实现),只是写入性能略低约 17%。

直接说结论:用 github.com/mattn/go-sqlite3 是当前最稳妥的本地 SQLite 方案,但必须配 C 编译环境;若想免 CGO、跨平台一键编译,就选 github.com/glebarez/go-sqlite(纯 Go 实现),只是写入性能略低约 17%。
sqlite3 驱动安装失败?大概率是缺 CGO 环境
绝大多数新手卡在这一步:go get github.com/mattn/go-sqlite3 报错,比如 exec: "gcc": executable file not found 或 cgo: disabled。
- 这是因为它依赖 C 标准库,必须启用 CGO:运行
CGO_ENABLED=1 go get github.com/mattn/go-sqlite3 - Windows 用户需装 MinGW-w64 或 TDM-GCC;macOS 需
xcode-select --install;Linux 装build-essential(Debian/Ubuntu)或gcc(CentOS/RHEL) - 如果你在 CI/CD 或 Alpine 容器里构建,
mattn/go-sqlite3会失败——这时别硬扛,直接切到glebarez/go-sqlite
database/sql.Open 之后,数据库文件没生成?检查 DSN 写法
sql.Open 只是初始化连接池,不真正建库;文件是否创建,取决于你后续有没有执行任何 SQL(比如 db.Ping() 或 db.Exec)。
- 正确写法:
db, err := sql.Open("sqlite3", "./data.db")—— 注意驱动名是sqlite3,不是sqlite - 内存数据库写法:
db, err := sql.Open("sqlite3", ":memory:"),每次重启就清空,适合测试 - 常见错误:路径含中文或空格,或权限不足(尤其 Linux 下写入
/tmp外的系统目录);建议统一用相对路径 +./xxx.db
事务不生效?记得显式 Commit 或 Rollback
SQLite 默认自动提交(autocommit),db.Exec 每条都是独立事务。要手动控制,必须用 db.Begin() 获取 *sql.Tx。
- 漏掉
tx.Commit()或tx.Rollback()会导致连接卡住、后续操作超时 - 不要在事务里混用
db.Query和tx.Query:前者走连接池,后者绑定事务上下文 - 示例关键片段:
tx, err := db.Begin() if err != nil { return err } _, err = tx.Exec("INSERT INTO users(name) VALUES(?)", "Alice") if err != nil { tx.Rollback() // 必须! return err } err = tx.Commit() // 必须! if err != nil { return err }
GORM 连 SQLite 很快,但迁移容易踩坑
用 GORM 的 AutoMigrate 确实省事,但它默认不处理字段类型变更(比如把 TEXT 改成 JSON),也不会删多余列。
- 首次建表没问题;但二次改结构时,
AutoMigrate只加字段、不删不改,旧数据可能读错 - 推荐做法:开发期用
db.Migrator().DropTable(&User{})清空重来;生产环境则手写ALTER TABLE迁移语句 - 注意 GORM 的 SQLite 驱动导入方式:
import _ "gorm.io/driver/sqlite",不是mattn/go-sqlite3
SQLite 文件就是数据库本身,备份只需拷贝 .db 文件;但别在程序运行时直接复制——它可能正在写入,导致损坏。真要热备份,得用 sqlite3_backup_init(C API)或第三方封装,Go 标准库不支持。这点最容易被忽略。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











