初始化

This commit is contained in:
2026-03-05 21:27:11 +08:00
commit 130de0fd5d
140 changed files with 21972 additions and 0 deletions

View File

@@ -0,0 +1,87 @@
---
name: database-migration
version: 3.0.0
description: "使用 Hyperf Migrations 安全管理数据库 Schema 变更。当需要创建表、添加字段或修改索引时使用。确保迁移安全可回滚。"
---
> ⚠️ 核心执行流程已在 `.cursor/rules/skill-database-migration.mdc` 中由 Cursor 自动注入。
> 本文件提供完整模板、代码示例和边缘场景处理,供 Agent 按需深入 Read。
# Hyperf Database Migration
## ⚠️ 安全等级ORANGE — 执行前必须确认
## 迁移核心原则
1. **每次变更都是迁移** — 禁止手动 DDL
2. **Schema 与 Data 严格分离** — DDL 和 DML 分文件
3. **迁移部署后不可变** — 已执行迁移禁止修改
4. **生产前向原则** — 回滚用新前向迁移修正
5. **新字段安全** — 新增字段必须 nullable 或有默认值
6. **迁移前测试** — 大表先在副本验证
## 目录约定
```
Case-Database-Backend/
├── database/
│ ├── migrations/ ← 迁移文件(已通过 DI 工厂注册到 Migrator
│ └── seeders/ ← 种子文件(已通过 DI 工厂注册到 Seed
```
路径配置说明:
- Hyperf 默认迁移路径为 `migrations/`,本项目通过 `App\Database\MigratorFactory` 覆盖为 `database/migrations/`
- Seeder 路径通过 `App\Database\SeedFactory` 覆盖为 `database/seeders/`
- `gen:migration` / `gen:seeder` 路径在 `config/autoload/devtool.php` 中配置
## 触发条件
用户要求修改数据库结构、添加/删除字段、创建/删除表、修改索引或关联。
## 执行流程
### 0. 加载规范
读取 `.cursor/rules/014-database.mdc`提取表设计、索引规则、Migration 写法、高并发注意事项。
### 1. 理解变更需求
确认:变更什么、是否涉及数据迁移、是否可逆、是否有线上数据、数据量级、环境阶段。
### 2. 生成迁移
```bash
php bin/hyperf.php gen:migration create_{{table_name}}_table
# 文件自动生成到 database/migrations/ 目录
# 命名: create_orders_table | add_status_to_orders | remove_legacy_field_from_users
```
### 3. 编写迁移
Schema::create / Schema::table含 id、audit 字段、索引。down() 必须完整可逆。幂等、Expand-Contract、批量迁移见 **Tier 3**
### 4. 高并发表设计检查
主键 BIGINT UNSIGNED、utf8mb4、金额 DECIMAL、状态 VARCHAR/TINYINT、外键索引、常用 WHERE 索引、复合索引最左前缀、单表索引 ≤6、JSON 仅非查询、避免过多 TEXT。
### 5. 执行与更新
`php bin/hyperf.php migrate``migrate:status``migrate:rollback``gen:model {{table_name}}`。更新 Model、Service、Repository、`docs/architecture/data-model.md`
## 验证
1. [ ] `migrate` 无错误
2. [ ] `migrate:rollback` 可回滚(开发)
3. [ ] Model `$fillable` / `$casts` 正确
4. [ ] 外键有索引
5. [ ] 新字段 nullable 或有默认值
6. [ ] Schema 与 Data 迁移分文件
7. [ ] 幂等检查通过
8. [ ] SQL 人工审查
9. [ ] data-model.md 已更新
## Tier 3 深度参考
| 文件 | 内容 |
|------|------|
| `references/migration-patterns.md` | 幂等、Expand-Contract、批量迁移、大表策略、危险操作 |

View File

@@ -0,0 +1,73 @@
# Database Migration — 迁移模式与示例
> 主流程见 SKILL.md本文档为幂等迁移、Expand-Contract、批量迁移、大表策略的完整实现。
## 幂等迁移
```php
public function up(): void
{
if (!Schema::hasTable('production_orders')) {
Schema::create('production_orders', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('order_no', 50)->unique();
$table->timestamps();
$table->softDeletes();
});
}
if (!Schema::hasColumn('production_orders', 'priority')) {
Schema::table('production_orders', function (Blueprint $table) {
$table->tinyInteger('priority')->default(0)->after('status');
});
}
if (!$this->hasIndex('production_orders', 'idx_orders_priority')) {
Schema::table('production_orders', function (Blueprint $table) {
$table->index('priority', 'idx_orders_priority');
});
}
}
```
## Expand-Contract 三阶段示例(字段重命名 username → display_name
Phase 1 EXPAND: 添加 display_name nullable。部署 v2 双写。
Phase 2 MIGRATE: 独立迁移文件批量 UPDATE 回填。部署 v3 读新写双。验证一致性。
Phase 3 CONTRACT: 删除 username。部署 v4 仅新字段。
时间线Day 1 加字段+双写Day 2 回填Day 3 读新写双+验证Day 7 删旧字段。
## 批量数据迁移模板
```php
$batchSize = 2000;
$lastId = 0;
while (true) {
$affected = Db::update("UPDATE users SET normalized_email = LOWER(email) WHERE id > ? AND normalized_email IS NULL ORDER BY id LIMIT ?", [$lastId, $batchSize]);
if ($affected === 0) break;
$lastId = Db::selectOne("SELECT MAX(id) AS max_id FROM users WHERE normalized_email IS NOT NULL AND id > ?", [$lastId])->max_id ?? $lastId + $batchSize;
usleep(100_000);
}
```
规则10005000 行/批、批次间 sleep、游标 WHERE id > ?、低峰期执行。
## 大表变更策略(百万级+
| 操作 | 风险 | 方案 |
|------|------|------|
| ADD COLUMN | 低 | 直接执行nullable 或有默认值 |
| ADD INDEX | 中 | ALGORITHM=INPLACE, LOCK=NONE |
| DROP COLUMN | 高 | 先移除代码→部署→下版本迁移删除 |
| ALTER TYPE | 高 | Expand-Contract |
| RENAME COLUMN | 高 | Expand-Contract |
| DROP TABLE | 极高 | 先重命名→观察一周→删除 |
## 危险操作清单
| 操作 | 缓解 |
|------|------|
| DROP TABLE | 先备份 |
| DROP COLUMN | 先移除代码引用 |
| ALTER TYPE | Expand-Contract |
| TRUNCATE | 禁止生产 |
| NOT NULL 无默认值 | 先 nullable→回填→再加约束 |

View File

@@ -0,0 +1,57 @@
# 数据库回滚模式 (Hyperf Migration)
## 安全回滚策略
### 添加字段(可回滚)
```php
// Migration up()
Schema::table('users', function (Blueprint $table) {
$table->string('avatar_url')->nullable()->after('email');
});
// Migration down()
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('avatar_url');
});
```
### 删除字段(不可逆 — 需预备份)
```sql
-- 删除前先备份
CREATE TABLE _backup_users_phone AS
SELECT id, phone FROM users WHERE phone IS NOT NULL;
```
### 重命名字段(分步迁移)
```php
// Step 1: 添加新列
Schema::table('users', function (Blueprint $table) {
$table->string('display_name')->nullable()->after('name');
});
// Step 2: 迁移数据
DB::statement('UPDATE users SET display_name = name');
// Step 3: 删除旧列(下一个迁移文件)
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('name');
});
```
### 类型变更(分步迁移)
```
Step 1: 添加新列 → Step 2: 迁移数据 → Step 3: 删除旧列
```
## 回滚命令
```bash
# 回滚最近一次迁移
php bin/hyperf.php migrate:rollback
# 回滚最近 N 次迁移
php bin/hyperf.php migrate:rollback --step=3
# 查看迁移状态
php bin/hyperf.php migrate:status
```