# 数据库迁移指南 本项目使用 **Flyway** 进行数据库版本管理和自动迁移。 ## 概述 Flyway 是一个数据库迁移工具,它能够: - 自动追踪数据库版本 - 按顺序执行迁移脚本 - 确保团队成员的数据库结构一致 - 支持回滚和修复 ## 工作原理 1. 应用启动时,Flyway 自动扫描 `src/main/resources/db/migration` 目录 2. 检查 `flyway_schema_history` 表,确定已执行的版本 3. 按版本号顺序执行未运行的迁移脚本 4. 记录执行结果到历史表 ## 迁移脚本命名规范 ``` V{版本号}__{描述}.sql ``` ### 命名规则 | 规则 | 说明 | 示例 | |------|------|------| | 前缀 | 必须以 `V` 开头(大写) | V1, V2, V10 | | 版本号 | 数字,支持小数点 | 1, 2, 2.1, 10 | | 分隔符 | **两个下划线** | `__` | | 描述 | 用下划线连接单词 | add_user_table | | 后缀 | 必须是 `.sql` | .sql | ### 正确示例 ``` V1__baseline.sql # 基线版本 V2__add_project_fields.sql # 添加项目字段 V3__create_order_table.sql # 创建订单表 V4__add_index_to_user.sql # 添加用户索引 V4.1__fix_user_column_type.sql # 修复用户列类型(小版本) V10__major_refactor.sql # 大版本重构 ``` ### 错误示例 ``` v1__init.sql # 错误:v 应该大写 V1_init.sql # 错误:只有一个下划线 V1-init.sql # 错误:使用了连字符 V1__init.SQL # 错误:后缀应该小写 init.sql # 错误:缺少版本前缀 ``` ## 如何添加新的迁移 ### 步骤 1:确定版本号 查看当前最新版本: ```bash ls src/main/resources/db/migration/ ``` 新版本号 = 最新版本号 + 1 ### 步骤 2:创建迁移脚本 在 `src/main/resources/db/migration/` 目录创建新文件: ```sql -- ===================================================== -- 迁移脚本: [描述] -- 版本: V{版本号} -- 描述: [详细说明] -- 日期: YYYY-MM-DD -- ===================================================== -- 你的 SQL 语句 ALTER TABLE xxx ADD COLUMN yyy VARCHAR(100); ``` ### 步骤 3:测试迁移 本地启动应用,观察日志: ``` Flyway Community Edition 9.x.x Successfully validated 3 migrations Current version of schema: 2 Migrating schema to version 3 - create_order_table Successfully applied 1 migration ``` ### 步骤 4:提交代码 ```bash git add src/main/resources/db/migration/V3__xxx.sql git commit -m "db: 添加xxx迁移脚本" git push ``` ## 最佳实践 ### 1. 幂等性脚本 编写可重复执行的脚本,避免重复执行报错: ```sql -- 添加列(如果不存在) SET @exist := (SELECT COUNT(*) FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'your_table' AND column_name = 'new_column'); SET @sql := IF(@exist = 0, 'ALTER TABLE your_table ADD COLUMN new_column VARCHAR(100)', 'SELECT 1'); PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt; ``` ### 2. 不要修改已执行的脚本 一旦迁移脚本被执行(已提交到版本库),**永远不要修改它**。 如果需要修复,创建新的迁移脚本: ``` V3__create_table.sql # 已执行,有错误 V4__fix_v3_error.sql # 新建脚本修复错误 ``` ### 3. 小步迁移 每个迁移脚本只做一件事: - V2__add_user_email.sql - V3__add_user_phone.sql - 不要: V2__add_user_email_and_phone_and_address.sql ### 4. 添加注释 ```sql -- ===================================================== -- 迁移脚本: 添加用户邮箱字段 -- 版本: V5 -- 描述: 为用户表添加邮箱字段,用于接收通知 -- 作者: 张三 -- 日期: 2024-12-29 -- 关联需求: JIRA-123 -- ===================================================== ``` ### 5. 备份数据 生产环境执行迁移前,务必备份数据库: ```bash mysqldump -u root -p martial_db > backup_$(date +%Y%m%d).sql ``` ## 常见问题 ### Q1: 迁移失败怎么办? 1. 查看错误日志,定位问题 2. 修复数据库中的问题(手动) 3. 修复迁移脚本 4. 执行 Flyway repair(如需要) ### Q2: 如何跳过某个版本? 不建议跳过版本。如果必须跳过,可以创建空脚本: ```sql -- V3__placeholder.sql -- 此版本跳过 SELECT 1; ``` ### Q3: 多人开发版本冲突怎么办? 使用日期时间作为版本号前缀: ``` V20241229001__add_field.sql V20241229002__fix_bug.sql ``` ### Q4: 如何查看迁移历史? ```sql SELECT * FROM flyway_schema_history ORDER BY installed_rank; ``` ## 目录结构 ``` src/main/resources/ └── db/ └── migration/ ├── V1__baseline.sql # 基线版本 ├── V2__add_project_fields.sql # 添加项目字段 └── V3__xxx.sql # 后续迁移... ``` ## 配置说明 application.yml 中的 Flyway 配置: ```yaml spring: flyway: enabled: true # 启用 Flyway locations: classpath:db/migration # 迁移脚本位置 table: flyway_schema_history # 版本历史表名 baseline-version: 0 # 基线版本号 baseline-on-migrate: true # 自动执行基线 validate-on-migrate: true # 校验迁移脚本 encoding: UTF-8 # 脚本编码 out-of-order: false # 禁止乱序执行 clean-disabled: true # 禁用清理(生产安全) ``` ## 参考资料 - [Flyway 官方文档](https://flywaydb.org/documentation/) - [Spring Boot Flyway 集成](https://docs.spring.io/spring-boot/docs/current/reference/html/howto.html#howto.data-initialization.migration-tool.flyway)