GORM 数据一致性校验
数据库迁移后必须验证数据一致性,本文介绍校验数据完整性与处理兼容性问题的核心方法。
什么是数据一致性校验
数据一致性校验指迁移完成后,验证数据在结构变更后是否保持完整、正确、无丢失。
基础校验方法
行数校验
最基础的校验是迁移前后行数一致。
Go
func VerifyRowCount(db *gorm.DB) error {
var oldCount, newCount int64
db.Table("users_old").Count(&oldCount)
db.Table("users").Count(&newCount)
if oldCount != newCount {
return fmt.Errorf("行数不一致: old=%d, new=%d", oldCount, newCount)
}
return nil
}
抽样校验
随机抽样验证字段值正确性。
Go
func VerifySampleData(db *gorm.DB) error {
// 随机抽取 100 条
var users []User
db.Order("RAND()").Limit(100).Find(&users)
for _, u := range users {
// 验证新字段值符合预期
if u.Status != "active" && u.Status != "inactive" {
return fmt.Errorf("用户 %d 状态异常: %s", u.ID, u.Status)
}
}
return nil
}
默认值变更处理
字段新增默认值时,历史数据可能为 NULL。
Go
// 迁移:新增列带默认值
db.Exec("ALTER TABLE users ADD COLUMN status VARCHAR(20) DEFAULT 'active'")
// 校验:历史数据默认值填充
var nullCount int64
db.Model(&User{}).Where("status IS NULL").Count(&nullCount)
if nullCount > 0 {
db.Model(&User{}).Where("status IS NULL").Update("status", "active")
}
字段类型转换
类型变更可能丢失精度或截断数据。
Go
// INT → BIGINT:通常安全
db.Exec("ALTER TABLE orders MODIFY id BIGINT")
// VARCHAR(50) → VARCHAR(20):可能截断
var truncatedCount int64
db.Raw(`
SELECT COUNT(*) FROM users
WHERE LENGTH(email) > 20
`).Scan(&truncatedCount)
if truncatedCount > 0 {
fmt.Printf("警告: %d 条数据将被截断\n", truncatedCount)
}
数据完整性校验
外键关联检查
迁移后验证关联数据完整性。
Go
func VerifyForeignKey(db *gorm.DB) error {
// 查找孤立的订单(用户不存在)
var orphanCount int64
db.Raw(`
SELECT COUNT(*) FROM orders o
LEFT JOIN users u ON o.user_id = u.id
WHERE u.id IS NULL
`).Scan(&orphanCount)
if orphanCount > 0 {
return fmt.Errorf("发现 %d 条孤立订单", orphanCount)
}
return nil
}
唯一约束检查
Go
func VerifyUniqueConstraint(db *gorm.DB) error {
// 检查是否有重复邮箱
var duplicates int64
db.Raw(`
SELECT COUNT(*) FROM (
SELECT email, COUNT(*) as cnt
FROM users
GROUP BY email
HAVING cnt > 1
) t
`).Scan(&duplicates)
if duplicates > 0 {
return fmt.Errorf("发现 %d 个重复邮箱", duplicates)
}
return nil
}
- **校验自动化:**将校验脚本集成到 CI/CD,迁移后自动执行。
- **阈值告警:**允许少量数据差异,但超出阈值应触发告警。
- **保留旧表:**迁移完成后保留旧表一段时间,便于回滚。
- **全量校验:**对核心数据(如金额、用户余额)应全量校验,而非抽样。
要点总结
| 校验类型 | 方法 | 适用场景 |
|---|---|---|
| 行数校验 | COUNT 对比 | 基础验证 |
| 抽样校验 | 随机抽取验证 | 字段值正确性 |
| 关联检查 | LEFT JOIN 查孤立数据 | 外键完整性 |
| 唯一约束 | GROUP BY + HAVING | 重复数据检测 |
- 迁移后必须校验数据一致性,确保数据无损。
- 基础校验:行数对比与抽样验证。
- 关注默认值变更与类型转换的兼容性问题。
- 核心数据应全量校验,校验脚本集成到 CI/CD。
存放路径: D:\git2\jwdev\articles\GORM\专家\数据迁移与版本管理\数据一致性校验.md
📝 发现内容有误?点击此处直接编辑