# 09 迁移与版本策略（complete vs migration vs tests）

本节解释仓库中与商城数据库相关的脚本如何分工、适合在什么场景使用，以及推荐的执行顺序。

---

## 1. 你现在有哪几类 SQL

### 1.1 “完整初始化脚本”（偏一次性创建）

- `doc_mall/database/complete_mall_database.sql`

特点：

- 覆盖范围大：表结构、索引、触发器、函数、视图、RLS 策略、初始化数据、SEO 函数等。
- 更像“新环境一键搭建”的脚本。

风险点：

- 若在已有环境重复执行，可能因为对象已存在/差异存在导致失败（脚本虽有部分 `IF NOT EXISTS`，但不是全幂等）。

适用场景：

- 新环境快速搭建
- 演示/验证/PoC

### 1.2 “迁移脚本”（偏幂等/可增量）

- `doc_mall/database/mall_migration.sql`

特点：

- 大量使用 `CREATE TABLE IF NOT EXISTS`、`CREATE INDEX IF NOT EXISTS`。
- 触发器创建使用 `DO $$ ... IF NOT EXISTS` 的方式避免重复创建报错。
- 插入初始化数据使用 `ON CONFLICT DO NOTHING`。

适用场景：

- 在已有数据库上“补齐商城模块”
- 生产环境更安全的增量迁移

### 1.3 “升级/差异修复脚本”（按数据库现状推荐执行）

从 `mall_sql/tests/mall_database_check.sql` 可看出项目侧存在“根据现状推荐脚本”的思路，提到：

- `mall_alter_upgrade.sql`：完整升级（表 + 字段 + 索引 + 函数）
- `mall_fields_only_upgrade.sql`：仅字段升级（最小化修改）
- `mall_migration.sql`：完整建表（全新部署/缺表时）
- `mall_seo_security.sql`：SEO 优化与安全策略

> 这些脚本在 `doc_mall/database/` 与 `mall_sql/migrations/` 中都有对应版本（具体以仓库实际文件为准）。

### 1.4 “检查/测试脚本”（偏验收与自检）

- `mall_sql/tests/mall_database_check.sql`
- `mall_sql/tests/validation_test.sql`
- `mall_sql/tests/mock_data_insert.sql`
- `mall_sql/tests/verify_mock_data_fix.sql`
- `mall_sql/tests/create_supabase_auth_users.sql`

适用场景：

- 验收环境是否缺表/缺字段/缺索引
- 生成建议与 ALTER 语句
- 插入 mock 数据用于联调

---

## 2. 推荐执行顺序（生产/测试通用）

### 2.1 新环境（从 0 到可用）

推荐路径（更稳妥）：

1. 执行 `mall_migration.sql`（幂等建表 + 基础索引 + 关键函数/触发器）
2. 执行 SEO 与安全策略脚本（如 `mall_seo_security.sql`，若 migration 未覆盖）
3. 执行订阅模块脚本（如需要）：`create_mall_subscription_tables.sql`
4. 执行检查脚本：`mall_database_check.sql`
5.（测试环境）执行 mock 数据脚本：`mock_data_insert.sql`

替代路径（快速但风险更高）：

- 直接执行 `complete_mall_database.sql` 一次性完成（适合演示/PoC）。

### 2.2 已有环境（补齐缺失）

1. 先执行检查脚本：`mall_database_check.sql`
2. 根据输出建议选择：
   - 缺字段多 + 缺表：`mall_alter_upgrade.sql`
   - 只缺字段：`mall_fields_only_upgrade.sql`
   - 只缺表：`mall_migration.sql`
3. 再执行 SEO/RLS 策略脚本（如缺失）
4. 再跑一次检查脚本确认

---

## 3. 版本差异与兼容性注意点

### 3.1 订单状态口径差异

在不同脚本中对 `order_status = 5` 的文字描述存在差异（“取消/取货”）。

建议：

- 在应用层/文档中统一口径
- 如需扩展状态，务必迁移更新 `CHECK` 约束与相关触发器逻辑

### 3.2 用户角色字段差异：`ak_users.role` vs `ml_user_profiles.user_type`

- `mall_migration.sql`：在 `ml_user_profiles` 引入 `user_type`
- `complete_mall_database.sql`：更多使用 `ak_users.role`（并在视图里做 role_name 映射）

建议：

- 明确项目最终“权威字段”是哪一个
- 避免两个口径长期并存造成权限与业务判断分裂

---

## 4. 推荐的团队规范

- 生产环境：优先使用“幂等迁移脚本 + 小步变更”，避免一次性大脚本覆盖执行。
- 每次变更：
  - 同步更新检查脚本/验收项
  - 明确回滚策略（尤其是约束、枚举、数据迁移）
- 对外接口依赖的 `cid/slug`：变更需谨慎（可能影响 SEO 与路由）。
