quanyoumi/backend/migrations/README.md

191 lines
3.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 数据库迁移系统
## 概述
本项目使用版本化的数据库迁移系统,支持增量更新和自动同步。
## 特性
- ✅ 版本管理:每个迁移有唯一版本号
- ✅ 增量执行:只执行未执行的迁移
- ✅ 自动运行:服务器启动时自动执行迁移
- ✅ 幂等性:重复执行不会出错
- ✅ 迁移记录:记录所有已执行的迁移
## 迁移文件命名规范
```
XXXX-description.js
```
- `XXXX`: 4位数字版本号如 0001, 0002
- `description`: 迁移描述(使用短横线分隔)
示例:
- `0001-add-danmaku-fields.js`
- `0002-add-user-avatar.js`
## 创建新迁移
### 1. 创建迁移文件
`backend/migrations/` 目录下创建新文件:
```javascript
/**
* 迁移: 添加用户头像字段
* 版本: 0002
* 日期: 2025-01-09
*/
module.exports = {
async up(manager) {
console.log(' - 添加 avatar 字段...');
await manager.executeSql(`
ALTER TABLE Users ADD COLUMN avatar TEXT;
`);
},
async down(manager) {
// 回滚逻辑(可选)
console.log(' - 回滚不支持');
}
};
```
### 2. 迁移方法
#### `up(manager)` - 升级
执行数据库变更的方法。
可用的 manager 方法:
- `executeSql(sql)`: 执行SQL语句
- `db`: 直接访问数据库连接
#### `down(manager)` - 回滚(可选)
回滚数据库变更的方法。
注意SQLite 不支持 DROP COLUMN回滚可能需要重建表。
## 执行迁移
### 自动执行(推荐)
服务器启动时会自动执行所有未执行的迁移:
```bash
# 开发环境
cd backend
npm start
# 生产环境Docker
docker-compose up -d
# 或
docker-compose restart
```
### 手动执行
#### 在容器内执行:
```bash
# Windows
migrate.bat
# Linux/Mac
chmod +x migrate.sh
./migrate.sh
```
#### 直接在容器中执行:
```bash
docker exec quanyoumi-app node /app/backend/migrations/index.js
```
## 迁移状态
迁移执行记录保存在 `migrations` 表中:
```sql
SELECT * FROM migrations;
```
输出示例:
```
id | version | name | executed_at
---+---------+-----------------------+---------------------
1 | 1 | add-danmaku-fields | 2025-01-09 10:30:00
2 | 2 | add-user-avatar | 2025-01-09 11:00:00
```
## 常见问题
### Q: 迁移失败怎么办?
A: 检查错误日志,修复问题后重新启动服务器。已执行的迁移不会重复执行。
### Q: 如何回滚迁移?
A: 目前不支持自动回滚。如需回滚,请手动修改数据库或创建新的迁移来撤销更改。
### Q: 可以修改已执行的迁移吗?
A: 不建议。已执行的迁移不应修改。如需更改,请创建新的迁移。
### Q: 迁移在什么时候执行?
A: 服务器启动时自动执行。也可以手动运行 `migrate.bat``migrate.sh`
## 最佳实践
1. **版本号递增**:新迁移的版本号应大于所有现有迁移
2. **描述清晰**:文件名和注释应清楚说明迁移目的
3. **测试迁移**:在开发环境测试后再部署到生产环境
4. **幂等性**:迁移应该可以安全地重复执行
5. **小步迭代**:每个迁移只做一件事,便于追踪和回滚
## 示例
### 添加新字段
```javascript
module.exports = {
async up(manager) {
await manager.executeSql(`
ALTER TABLE Activities ADD COLUMN featured INTEGER DEFAULT 0;
`);
}
};
```
### 创建新表
```javascript
module.exports = {
async up(manager) {
await manager.executeSql(`
CREATE TABLE IF NOT EXISTS Comments (
id INTEGER PRIMARY KEY AUTOINCREMENT,
activityId INTEGER NOT NULL,
userId INTEGER NOT NULL,
content TEXT NOT NULL,
createdAt DATETIME DEFAULT CURRENT_TIMESTAMP
);
`);
}
};
```
### 修改数据
```javascript
module.exports = {
async up(manager) {
await manager.executeSql(`
UPDATE Activities SET status = 'completed' WHERE endTime < datetime('now');
`);
}
};
```