diff --git a/docs/DATABASE_MIGRATION.md b/docs/DATABASE_MIGRATION.md
new file mode 100644
index 0000000..c54b9cd
--- /dev/null
+++ b/docs/DATABASE_MIGRATION.md
@@ -0,0 +1,224 @@
+# 数据库迁移指南
+
+本项目使用 **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)
diff --git a/pom.xml b/pom.xml
index 4b6d0ef..f29c360 100644
--- a/pom.xml
+++ b/pom.xml
@@ -228,6 +228,16 @@
lombok
provided
+
+
+
+ org.flywaydb
+ flyway-core
+
+
+ org.flywaydb
+ flyway-mysql
+
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index a843cf3..c351568 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -50,6 +50,27 @@ spring:
session-stat-enable: true
session-stat-max-count: 10
+
+# Flyway 数据库迁移配置
+ flyway:
+ enabled: true
+ # 迁移脚本位置
+ 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
+ # 是否清理数据库(生产环境务必设为false)
+ clean-disabled: true
+
# mybatis
mybatis-plus:
mapper-locations: classpath:org/springblade/**/mapper/*Mapper.xml
diff --git a/src/main/resources/db/migration/V1__baseline.sql b/src/main/resources/db/migration/V1__baseline.sql
new file mode 100644
index 0000000..fdf459d
--- /dev/null
+++ b/src/main/resources/db/migration/V1__baseline.sql
@@ -0,0 +1,12 @@
+-- =====================================================
+-- Flyway 基线脚本
+-- 版本: V1
+-- 描述: 记录当前数据库结构基线,不执行任何操作
+-- 日期: 2024-12-29
+-- =====================================================
+
+-- 此脚本作为基线版本,用于标记已有数据库的初始状态
+-- 由于 baseline-on-migrate: true,Flyway 会自动将此版本标记为已执行
+-- 后续的迁移脚本从 V2 开始
+
+SELECT 1;
diff --git a/src/main/resources/db/migration/V2__add_project_fields.sql b/src/main/resources/db/migration/V2__add_project_fields.sql
new file mode 100644
index 0000000..396ad96
--- /dev/null
+++ b/src/main/resources/db/migration/V2__add_project_fields.sql
@@ -0,0 +1,42 @@
+-- =====================================================
+-- 迁移脚本: 添加项目表字段
+-- 版本: V2
+-- 描述: 为 martial_project 表添加 event_type 和报名时间字段
+-- 日期: 2024-12-29
+-- =====================================================
+
+-- 添加 event_type 字段(如果不存在)
+SET @exist := (SELECT COUNT(*) FROM information_schema.columns
+ WHERE table_schema = DATABASE()
+ AND table_name = 'martial_project'
+ AND column_name = 'event_type');
+SET @sql := IF(@exist = 0,
+ 'ALTER TABLE martial_project ADD COLUMN event_type int DEFAULT NULL COMMENT "项目类型: 1-套路 2-散打 3-器械 4-对练" AFTER category',
+ 'SELECT 1');
+PREPARE stmt FROM @sql;
+EXECUTE stmt;
+DEALLOCATE PREPARE stmt;
+
+-- 添加 registration_start_time 字段(如果不存在)
+SET @exist := (SELECT COUNT(*) FROM information_schema.columns
+ WHERE table_schema = DATABASE()
+ AND table_name = 'martial_project'
+ AND column_name = 'registration_start_time');
+SET @sql := IF(@exist = 0,
+ 'ALTER TABLE martial_project ADD COLUMN registration_start_time datetime DEFAULT NULL COMMENT "报名开始时间" AFTER price',
+ 'SELECT 1');
+PREPARE stmt FROM @sql;
+EXECUTE stmt;
+DEALLOCATE PREPARE stmt;
+
+-- 添加 registration_end_time 字段(如果不存在)
+SET @exist := (SELECT COUNT(*) FROM information_schema.columns
+ WHERE table_schema = DATABASE()
+ AND table_name = 'martial_project'
+ AND column_name = 'registration_end_time');
+SET @sql := IF(@exist = 0,
+ 'ALTER TABLE martial_project ADD COLUMN registration_end_time datetime DEFAULT NULL COMMENT "报名结束时间" AFTER registration_start_time',
+ 'SELECT 1');
+PREPARE stmt FROM @sql;
+EXECUTE stmt;
+DEALLOCATE PREPARE stmt;