从SQLite到MongoDB:用golang-migrate实现零停机数据迁移
为什么需要跨数据库迁移?
你是否遇到过这些问题:SQLite性能瓶颈、用户数据量激增、需要更灵活的数据结构?从关系型数据库迁移到NoSQL数据库(如MongoDB)是解决这些问题的常见方案。本文将以实际案例演示如何使用golang-migrate/migrate工具实现从SQLite到MongoDB的平滑迁移,确保业务零停机。
读完本文你将掌握:
- 两种数据库迁移文件的编写规范
- 使用migrate CLI执行跨数据库迁移
- 数据类型转换的最佳实践
- 迁移过程中的回滚策略
迁移前的准备工作
环境要求
确保已安装golang-migrate CLI工具:
go install -tags 'sqlite3 mongodb' github.com/golang-migrate/migrate/v4/cmd/migrate@latest
文件结构
项目中需要为两种数据库创建独立的迁移文件目录:
database/
├── sqlite/
│ └── examples/
│ └── migrations/ # SQLite迁移文件
└── mongodb/
└── examples/
└── migrations/ # MongoDB迁移文件
SQLite到MongoDB的核心差异
数据模型对比
SQLite使用表结构存储数据:
-- [SQLite创建表](https://link.gitcode.com/i/a853a9fa3508667a7c32c9f49e5e18db)
CREATE TABLE pets (
name string
);
MongoDB使用JSON文档存储数据:
-- [MongoDB创建用户](https://link.gitcode.com/i/a11ac30f0d7af85ff6ef06dbd82225d4)
[
{
"createUser": "deminem",
"pwd": "gogo",
"roles": [
{
"role": "readWrite",
"db": "testMigration"
}
]
}
]
迁移文件命名规范
根据MIGRATIONS.md,迁移文件需遵循以下命名格式:
{version}_{title}.up.{extension}
{version}_{title}.down.{extension}
SQLite使用.sql扩展名,MongoDB使用.json扩展名。推荐使用时间戳作为版本号,如:
1620000000_create_pets.up.sql # SQLite
1620000000_create_pets.up.json # MongoDB
实现迁移的步骤
1. 导出SQLite数据
创建SQLite数据导出脚本(export_sqlite.sh):
sqlite3 data.db .dump > export.sql
2. 转换数据格式
编写数据转换工具,将SQL INSERT语句转换为MongoDB插入命令:
// 伪代码示例
func convertSQLToMongo(sql string) []bson.M {
// 解析SQL语句
// 转换为BSON文档
return bsonDocs
}
3. 创建MongoDB迁移文件
创建MongoDB集合和索引:
// 002_create_pets_collection.up.json
[
{
"createCollection": "pets"
},
{
"createIndex": {
"collection": "pets",
"index": { "name": 1 },
"unique": true
}
}
]
4. 执行迁移命令
# 升级到最新版本
migrate -database mongodb://localhost:27017/test -source file://mongodb/migrations up
# 如需回滚
migrate -database mongodb://localhost:27017/test -source file://mongodb/migrations down 1
常见问题与解决方案
数据类型转换
| SQLite类型 | MongoDB类型 | 转换方法 |
|---|---|---|
| string | String | 直接映射 |
| INTEGER | Int32/Int64 | 根据数值范围转换 |
| REAL | Double | 直接映射 |
| BLOB | BinData | 使用Base64编码 |
迁移回滚策略
遵循MIGRATIONS.md中的可逆性原则,为每个up迁移文件创建对应的down文件:
// 001_create_user.down.json
[
{
"dropUser": "deminem"
}
]
迁移后的验证
执行以下命令验证数据完整性:
# 检查MongoDB集合数据
mongo testMigration --eval "db.pets.find()"
# 对比记录数
sqlite3 data.db "SELECT COUNT(*) FROM pets;"
mongo testMigration --eval "db.pets.countDocuments()"
总结与最佳实践
- 版本控制:始终使用版本控制系统管理迁移文件
- 测试优先:在开发环境验证所有迁移脚本
- 备份策略:迁移前完整备份SQLite数据库
- 监控迁移:实时监控迁移过程,设置超时告警
通过golang-migrate/migrate工具,我们可以轻松实现不同数据库之间的迁移。项目支持多达20+种数据库类型,更多数据库驱动请查看database/目录。
扩展阅读
如果觉得本文有帮助,请点赞收藏,并关注后续关于分库分表迁移的高级教程!
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



