Compare commits
1 Commits
v1-initial
...
v2-db-revi
| Author | SHA1 | Date | |
|---|---|---|---|
| 3f5652e235 |
@@ -1,13 +1,14 @@
|
|||||||
# iShare 数据库设计概要
|
# iShare 数据库设计概要
|
||||||
|
|
||||||
> 基于 DATABASE_DESIGN_V2.md 整理
|
> 版本:v3(基于 v2 评审修订)
|
||||||
> 评审时间:2026-02-17
|
> 修订时间:2026-02-17
|
||||||
> 完整建表 SQL:`db/ishare_schema_v2.sql`
|
> 完整建表 SQL(v2 基础版):`db/ishare_schema_v2.sql`
|
||||||
|
> 增量变更 SQL(v2→v3):`db/ishare_schema_v3_delta.sql`
|
||||||
> 完整字段说明:`DATABASE_DESIGN_V2.md`
|
> 完整字段说明:`DATABASE_DESIGN_V2.md`
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 一、表总览(23 张表)
|
## 一、表总览(27 张表)
|
||||||
|
|
||||||
### 1.1 App 基础表(复用 PigX,共 9 张)
|
### 1.1 App 基础表(复用 PigX,共 9 张)
|
||||||
|
|
||||||
@@ -23,58 +24,63 @@
|
|||||||
| 8 | `app_page` | 页面配置 | 沿用 |
|
| 8 | `app_page` | 页面配置 | 沿用 |
|
||||||
| 9 | `app_tabbar` | 底部导航 | 沿用 |
|
| 9 | `app_tabbar` | 底部导航 | 沿用 |
|
||||||
|
|
||||||
### 1.2 业务表(iShare 专属,共 14 张)
|
### 1.2 业务表(iShare 专属,共 18 张)
|
||||||
|
|
||||||
#### 平台与产品
|
#### 平台与产品
|
||||||
|
|
||||||
| # | 表名 | 说明 |
|
| # | 表名 | 说明 | v3 变更 |
|
||||||
|---|------|------|
|
|---|------|------|---------|
|
||||||
| 10 | `as_platform_type` | 平台分类(视频/音乐/AI等) |
|
| 10 | `as_platform_type` | 平台分类(视频/音乐/AI等) | — |
|
||||||
| 11 | `as_platform` | 流媒体平台(Netflix/Spotify等) |
|
| 11 | `as_platform` | 流媒体平台 | — |
|
||||||
| 12 | `as_sub_plan` | 订阅计划(高级版/家庭版等) |
|
| 12 | `as_sub_plan` | 订阅计划 | — |
|
||||||
| 13 | `as_sub_payroll` | 付费方案(月/季/年,含价格) |
|
| 13 | `as_sub_payroll` | 付费方案(月/季/年) | — |
|
||||||
| 14 | `as_sub_product` | 合租商品(自营 or 个人发布) |
|
| 14 | `as_sub_product` | 合租商品 | 移除 `sub_plan_ids` 逗号字段 |
|
||||||
| 15 | `as_sub_account` | 平台账号凭据(AES 加密存储) |
|
| 15 | `as_product_plan_rel` | 产品-计划 M:N 关联表 | ✨ 新增(I2 修复) |
|
||||||
| 16 | `as_sub_product_comment` | 商品评价 |
|
| 16 | `as_sub_account` | 平台账号凭据(AES 加密) | — |
|
||||||
|
| 17 | `as_sub_product_comment` | 商品评价 | — |
|
||||||
|
| 18 | `as_banner` | 首页 Banner 广告位 | ✨ 新增(I1 修复) |
|
||||||
|
|
||||||
#### 订阅与订单
|
#### 订阅与订单
|
||||||
|
|
||||||
| # | 表名 | 说明 |
|
| # | 表名 | 说明 | v3 变更 |
|
||||||
|---|------|------|
|
|---|------|------|---------|
|
||||||
| 17 | `as_user_sub` | 合租槽/共享池(一个账号对应一个槽) |
|
| 19 | `as_user_sub` | 合租槽/共享池 | 补充索引 |
|
||||||
| 18 | `as_user_sub_member` | 个人订阅记录(原版缺失最关键表) |
|
| 20 | `as_user_sub_member` | 个人订阅记录 | 移除唯一键、新增 status=4、补充索引 |
|
||||||
| 19 | `as_order` | 订单(含状态机、价格快照) |
|
| 21 | `as_order` | 订单(含状态机、价格快照) | 补充索引 |
|
||||||
|
|
||||||
#### 钱包与推广
|
#### 钱包与推广
|
||||||
|
|
||||||
| # | 表名 | 说明 |
|
| # | 表名 | 说明 | v3 变更 |
|
||||||
|---|------|------|
|
|---|------|------|---------|
|
||||||
| 20 | `as_wallet` | 用户钱包(乐观锁防并发) |
|
| 22 | `as_recharge` | 钱包充值单 | ✨ 新增(R1 修复) |
|
||||||
| 21 | `as_wallet_log` | 钱包流水(含余额快照便于对账) |
|
| 23 | `as_wallet` | 用户钱包(乐观锁防并发) | — |
|
||||||
| 22 | `as_invite` | 邀请关系与返现 |
|
| 24 | `as_wallet_log` | 钱包流水(含余额快照) | — |
|
||||||
| 23 | `as_notification` | 系统通知(续费提醒/订单/公告/奖励) |
|
| 25 | `as_invite` | 邀请关系与返现 | — |
|
||||||
|
| 26 | `as_notification` | 系统通知 | 补充索引 |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 二、核心 ER 关系概览
|
## 二、核心 ER 关系概览(v3)
|
||||||
|
|
||||||
```
|
```
|
||||||
as_platform_type (1) ──< (N) as_platform
|
as_platform_type (1) ──< (N) as_platform
|
||||||
as_platform (1) ──< (N) as_sub_plan
|
as_platform (1) ──< (N) as_sub_plan
|
||||||
as_sub_plan (1) ──< (N) as_sub_payroll
|
as_sub_plan (1) ──< (N) as_sub_payroll
|
||||||
as_sub_plan (N) >──< (N) as_sub_product ← sub_plan_ids 逗号分隔(待决策改关联表)
|
as_sub_plan (N) >──< (N) as_sub_product [via as_product_plan_rel] ← v3 改为关联表
|
||||||
as_platform (1) ──< (N) as_sub_product [platform_id 冗余加速查询]
|
as_platform (1) ──< (N) as_sub_product [platform_id 冗余加速查询]
|
||||||
|
|
||||||
as_sub_product (1) ──< (N) as_sub_account [product_id]
|
as_sub_product (1) ──< (N) as_sub_account [product_id]
|
||||||
as_sub_product (1) ──< (N) as_user_sub [product_id]
|
as_sub_product (1) ──< (N) as_user_sub [product_id]
|
||||||
as_user_sub (1) ──< (N) as_user_sub_member [sub_id] ← 新增关键关联
|
as_user_sub (1) ──< (N) as_user_sub_member [sub_id]
|
||||||
|
|
||||||
as_sub_product (1) ──< (N) as_order [product_id]
|
as_sub_product (1) ──< (N) as_order [product_id]
|
||||||
as_order (1) ──< (1) as_user_sub_member [order_id]
|
as_order (1) ──< (1) as_user_sub_member [order_id]
|
||||||
|
|
||||||
app_user (1) ──< (1) as_wallet
|
app_user (1) ──< (1) as_wallet
|
||||||
as_wallet (1) ──< (N) as_wallet_log
|
as_wallet (1) ──< (N) as_wallet_log
|
||||||
|
as_wallet (1) ──< (N) as_recharge [user_id] ← v3 新增
|
||||||
app_user (1) ──< (N) as_order
|
app_user (1) ──< (N) as_order
|
||||||
|
app_user (1) ──< (N) as_recharge [user_id] ← v3 新增
|
||||||
app_user (1) ──< (N) as_user_sub_member
|
app_user (1) ──< (N) as_user_sub_member
|
||||||
app_user (1) ──< (N) as_invite [as inviter]
|
app_user (1) ──< (N) as_invite [as inviter]
|
||||||
app_user (1) ──< (1) as_invite [as invitee]
|
app_user (1) ──< (1) as_invite [as invitee]
|
||||||
@@ -93,20 +99,33 @@ app_user (1) ──< (N) as_notification
|
|||||||
[已支付/已完成] ─→ 退款 ─→ [已退款]
|
[已支付/已完成] ─→ 退款 ─→ [已退款]
|
||||||
```
|
```
|
||||||
|
|
||||||
### 3.2 个人订阅(as_user_sub_member)
|
### 3.2 充值单(as_recharge) ← v3 新增
|
||||||
|
|
||||||
```
|
```
|
||||||
[待激活] ─→ 订单完成 ─→ [使用中]
|
[待支付(0)] ─→ 外部支付成功 ─→ [已到账(1)]
|
||||||
├─→ 到期 ─→ [已到期] ─→ 续费 ─→ [使用中]
|
─→ 15min 超时 ─→ [已取消(3)]
|
||||||
└─→ 主动退订 ─→ [已退订]
|
─→ 支付失败 ─→ [支付失败(2)]
|
||||||
|
人工充值:管理员操作 → 直接创建 status=1 记录
|
||||||
```
|
```
|
||||||
|
|
||||||
### 3.3 合租槽(as_user_sub)
|
### 3.3 个人订阅(as_user_sub_member) ← v3 修订
|
||||||
|
|
||||||
```
|
```
|
||||||
[可加入(0)] ─→ 席位满(capacity_loaded = capacity) ─→ [已满(1)]
|
[待激活(0)] ─→ 订单完成 ─→ [使用中(1)]
|
||||||
|
[等待车主(4)] ← 广场拼车付款后,等待车主录入凭据
|
||||||
|
[等待车主(4)] ─→ 车主录入凭据 ─→ [使用中(1)]
|
||||||
|
[使用中(1)] ─→ 到期 ─→ [已到期(2)] ─→ 续费 ─→ [使用中(1)] 新建记录
|
||||||
|
─→ 主动退订 ─→ [已退订(3)]
|
||||||
|
```
|
||||||
|
|
||||||
|
> **v3 修订**:移除 UNIQUE(sub_id, user_id),续费时新建记录(旧记录置2=已到期),保留完整历史
|
||||||
|
|
||||||
|
### 3.4 合租槽(as_user_sub)
|
||||||
|
|
||||||
|
```
|
||||||
|
[可加入(0)] ─→ 席位满 ─→ [已满(1)]
|
||||||
[可加入/已满] ─→ 到期 ─→ [已到期(2)]
|
[可加入/已满] ─→ 到期 ─→ [已到期(2)]
|
||||||
[可加入/已满] ─→ 车主关闭 ─→ [已关闭(3)]
|
─→ 车主关闭 ─→ [已关闭(3)]
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -116,96 +135,108 @@ app_user (1) ──< (N) as_notification
|
|||||||
### 4.1 席位超卖防护(乐观锁)
|
### 4.1 席位超卖防护(乐观锁)
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
-- 购买时原子性占位,row affected = 0 则席位已满
|
-- 购买时原子性占位,affected rows = 0 则席位已满
|
||||||
UPDATE as_user_sub
|
UPDATE as_user_sub
|
||||||
SET capacity_loaded = capacity_loaded + 1
|
SET capacity_loaded = capacity_loaded + 1
|
||||||
WHERE id = ? AND capacity_loaded < capacity
|
WHERE id = ? AND capacity_loaded < capacity;
|
||||||
```
|
```
|
||||||
|
|
||||||
### 4.2 账号凭据加密
|
### 4.2 账号凭据加密
|
||||||
|
|
||||||
- 算法:AES-256-GCM(`as_sub_account.encrypt_type = 1`)
|
- 算法:AES-256-GCM(`as_sub_account.encrypt_type = 1`)
|
||||||
- `account_passwd`:密文(Base64)
|
- `account_passwd`:密文(Base64)
|
||||||
- `passwd_salt`:随机 IV(16 字节 Base64,**原设计为 int 已修复**)
|
- `passwd_salt`:随机 IV(16 字节 Base64)
|
||||||
- 密钥:服务端环境变量,不入库
|
- 密钥:服务端环境变量,不入库
|
||||||
- 查看凭据:仅限 `as_user_sub_member.status = 1(使用中)`,服务端解密后返回明文,不记录日志
|
- 查看凭据:仅限 `as_user_sub_member.status = 1`,服务端解密后返回明文,不记录日志
|
||||||
|
|
||||||
### 4.3 钱包余额并发控制(乐观锁)
|
### 4.3 钱包余额并发控制(乐观锁)
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
UPDATE as_wallet
|
UPDATE as_wallet
|
||||||
SET balance = balance - ?, version = version + 1
|
SET balance = balance - ?, version = version + 1
|
||||||
WHERE user_id = ? AND version = ? AND balance >= ?
|
WHERE user_id = ? AND version = ? AND balance >= ?;
|
||||||
-- row affected = 0:并发冲突或余额不足
|
-- affected rows = 0:并发冲突或余额不足
|
||||||
```
|
```
|
||||||
|
|
||||||
### 4.4 订阅到期定时任务(建议每日 02:00)
|
### 4.4 续费记录设计
|
||||||
|
|
||||||
```
|
- 续费时**新建** `as_user_sub_member` 记录,旧记录 `status` 置为 2(已到期)
|
||||||
1. expire_time < now() + 7天 且 status=1 → 推送续费提醒通知
|
- 同一 `sub_id + user_id` 只允许一条 `status = 1` 的记录(应用层强制)
|
||||||
2. expire_time < now() 且 status=1 → 标记 status=2(已到期)
|
- 历史续费记录完整保留,支持对账和退款审计
|
||||||
→ as_user_sub.capacity_loaded -1(释放席位)
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
### 4.5 产品-计划 M:N 查询
|
||||||
|
|
||||||
## 五、设计评审问题清单
|
|
||||||
|
|
||||||
> 评审时间:2026-02-17
|
|
||||||
|
|
||||||
### 🔴 严重(影响核心功能,需修复)
|
|
||||||
|
|
||||||
| # | 问题 | 影响 | 建议方案 |
|
|
||||||
|---|------|------|----------|
|
|
||||||
| R1 | **充值流水追踪缺失** | 一旦接入外部支付充值(支付宝/微信),充值过程(待支付→成功)无法追踪,无法对账 | 新增 `as_recharge` 表(order_no / user_id / amount / pay_type / pay_no / status / expire_time / pay_time)|
|
|
||||||
| R2 | **`as_user_sub_member` 唯一键问题** | `UNIQUE(sub_id, user_id)` 导致续费只能覆盖,历史续费记录丢失,退款/对账有问题 | 去掉唯一键;改为逻辑约束:同 `sub_id+user_id` 只允许一条 `status=1` 记录,续费时新增记录(旧的置为2=已到期) |
|
|
||||||
|
|
||||||
### 🟠 重要(功能不完整,建议修复)
|
|
||||||
|
|
||||||
| # | 问题 | 影响 | 建议方案 |
|
|
||||||
|---|------|------|----------|
|
|
||||||
| I1 | **Banner 广告位表缺失** | 首页有 Banner 需求,但无对应表 | 新增 `as_banner`(image_url / link_url / link_type / sort_order / status / start_time / end_time)|
|
|
||||||
| I2 | **`as_sub_product.sub_plan_ids` 逗号分隔反范式** | 反向查询(某计划关联哪些商品)需 LIKE 模糊查,不走索引 | 改为关联表 `as_product_plan_rel(product_id, plan_id)`(现在改成本最低)|
|
|
||||||
| I3 | **SYSTEM_DESIGN.md 与 DATABASE_DESIGN_V2.md 字段不一致** | 开发时若参考旧文档会导致实现错误 | 更新 SYSTEM_DESIGN.md ER 图:`user_sub_id→member_id`、`main_account→account_id`、移除已不存在的 `available_seats` |
|
|
||||||
|
|
||||||
### 🟡 轻微(可优化,不影响上线)
|
|
||||||
|
|
||||||
| # | 问题 | 影响 | 建议方案 |
|
|
||||||
|---|------|------|----------|
|
|
||||||
| L1 | **广场拼车凭据录入状态未建模** | 个人拼车:用户付款后,车主需事后录入凭据,这段时间状态不明确 | `as_user_sub_member.status` 增加值:`4=等待车主录入凭据` |
|
|
||||||
| L2 | **缺少关键索引规划** | 高频查询无索引影响性能 | 见下方索引清单 |
|
|
||||||
|
|
||||||
### 建议索引清单
|
|
||||||
|
|
||||||
```sql
|
```sql
|
||||||
-- 我的订阅列表
|
-- 商品详情:该商品关联哪些订阅计划
|
||||||
CREATE INDEX idx_member_user_status ON as_user_sub_member(user_id, status);
|
SELECT sp.* FROM as_sub_plan sp
|
||||||
-- 定时任务扫描到期
|
JOIN as_product_plan_rel r ON r.plan_id = sp.id
|
||||||
CREATE INDEX idx_member_expire ON as_user_sub_member(expire_time, status);
|
WHERE r.product_id = ?
|
||||||
-- 用户订单列表
|
ORDER BY r.sort_order;
|
||||||
CREATE INDEX idx_order_user_status ON as_order(user_id, status);
|
|
||||||
-- 订单号查询(已设 UNIQUE,跳过)
|
-- 计划维度:哪些商品使用了该计划
|
||||||
-- 未读通知数
|
SELECT p.* FROM as_sub_product p
|
||||||
CREATE INDEX idx_notif_user_read ON as_notification(user_id, is_read);
|
JOIN as_product_plan_rel r ON r.product_id = p.id
|
||||||
-- 合租槽状态
|
WHERE r.plan_id = ? AND p.status = 1;
|
||||||
CREATE INDEX idx_sub_product_status ON as_user_sub(product_id, status);
|
```
|
||||||
-- 账号凭据查询
|
|
||||||
CREATE INDEX idx_account_product ON as_sub_account(product_id, status);
|
### 4.6 订阅到期定时任务(每日 02:00)
|
||||||
|
|
||||||
|
```
|
||||||
|
1. expire_time < now() + 7天 且 status=1 → 推送续费提醒通知(as_notification)
|
||||||
|
2. expire_time < now() 且 status=1 → 标记 status=2(已到期)
|
||||||
|
→ as_user_sub.capacity_loaded -1(释放席位)
|
||||||
|
3. as_order.expire_time < now() 且 status=0 → 标记 status=4(已取消,释放席位预留)
|
||||||
|
4. as_recharge.expire_time < now() 且 status=0 → 标记 status=3(已取消)
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 六、待决策项(需 Ami 确认)
|
## 五、关键索引清单
|
||||||
|
|
||||||
|
| 表 | 索引 | 用途 |
|
||||||
|
|----|------|------|
|
||||||
|
| `as_user_sub_member` | `(user_id, status)` | 我的订阅列表 |
|
||||||
|
| `as_user_sub_member` | `(expire_time, status)` | 定时任务扫描到期 |
|
||||||
|
| `as_order` | `(user_id, status)` | 用户订单列表 |
|
||||||
|
| `as_order` | `order_no` UNIQUE | 订单号查询 |
|
||||||
|
| `as_notification` | `(user_id, is_read)` | 未读通知数 |
|
||||||
|
| `as_user_sub` | `(product_id, status)` | 商品可用合租槽 |
|
||||||
|
| `as_sub_account` | `(product_id, status)` | 产品账号列表 |
|
||||||
|
| `as_sub_product` | `(product_type, status)` | 广场/自营分类查询 |
|
||||||
|
| `as_banner` | `(status, sort_order)` | 首页 Banner 展示 |
|
||||||
|
| `as_banner` | `(start_time, end_time)` | 时间段筛选 |
|
||||||
|
| `as_recharge` | `(user_id, status)` | 充值记录查询 |
|
||||||
|
| `as_product_plan_rel` | `(product_id)` / `(plan_id)` | M:N 双向查询 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 六、v2 → v3 变更记录
|
||||||
|
|
||||||
|
| 问题 | 类型 | 处理方式 | 结果 |
|
||||||
|
|------|------|----------|------|
|
||||||
|
| R1 充值流水缺失 | 🔴 严重 | 新增 `as_recharge` 表 | ✅ 已修复 |
|
||||||
|
| R2 续费历史丢失 | 🔴 严重 | 移除 `as_user_sub_member` UNIQUE KEY;续费改为新建记录 | ✅ 已修复 |
|
||||||
|
| I1 Banner 表缺失 | 🟠 重要 | 新增 `as_banner` 表 | ✅ 已修复 |
|
||||||
|
| I2 M:N 逗号分隔 | 🟠 重要 | 新增 `as_product_plan_rel`;移除 `sub_plan_ids` 字段 | ✅ 已修复 |
|
||||||
|
| I3 文档字段不一致 | 🟠 重要 | 本文档统一使用 v2 修订后字段名 | ✅ 已同步 |
|
||||||
|
| L1 拼车凭据状态 | 🟡 轻微 | `as_user_sub_member.status` 增加值 4=等待车主录入凭据 | ✅ 已修复 |
|
||||||
|
| L2 索引规划缺失 | 🟡 轻微 | 补充 12 项关键索引(见上表) | ✅ 已修复 |
|
||||||
|
|
||||||
|
**表数量变化:v2(23张)→ v3(27张,新增 as_recharge / as_banner / as_product_plan_rel)**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 七、待决策项(需 Ami 确认)
|
||||||
|
|
||||||
| # | 问题 | 选项 |
|
| # | 问题 | 选项 |
|
||||||
|---|------|------|
|
|---|------|------|
|
||||||
| 1 | 付费方式一期支持哪些? | A) 仅余额(人工充值)B) 余额+支付宝 C) 三种都支持 |
|
| 1 | 付费方式一期支持哪些? | A) 仅余额(人工充值)B) 余额+支付宝 C) 三种都支持 |
|
||||||
| 2 | 拼车广场是否需要审核流程? | A) 管理员审核 B) 自动上架 C) 仅自营,无拼车广场 |
|
| 2 | 拼车广场是否需要审核流程? | A) 管理员审核 B) 自动上架 C) 仅自营,无拼车广场 |
|
||||||
| 3 | 账号凭据展示方式? | A) 直接明文 B) 需二次验证(短信/密码)C) 限时展示(30s后隐藏)|
|
| 3 | 账号凭据展示方式? | A) 直接明文 B) 需二次验证 C) 限时展示(30s后隐藏) |
|
||||||
| 4 | 邀请返现比例和条件? | 需定义:返现金额/比例,是否有上限 |
|
| 4 | 邀请返现比例和条件? | 需定义:金额/比例,是否有上限 |
|
||||||
| 5 | `as_sub_product` 的多计划关联是否改为关联表? | A) 保持逗号分隔 B) 改关联表(**推荐**,趁现在改成本最低)|
|
| 5 | ~~sub_plan_ids 是否改关联表?~~ | ✅ v3 已改为关联表 `as_product_plan_rel` |
|
||||||
| 6 | 提现功能是否一期上线? | A) 一期上 B) 二期(一期只充值不提现) |
|
| 6 | 提现功能是否一期上线? | A) 一期上 B) 二期(一期只充值不提现) |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
*文档由 AI 评审生成 · 最后更新:2026-02-17*
|
*最后更新:2026-02-17 · v3*
|
||||||
|
|||||||
129
db/ishare_schema_v3_delta.sql
Normal file
129
db/ishare_schema_v3_delta.sql
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
-- ============================================================
|
||||||
|
-- iShare 数据库设计 v2 → v3 增量脚本
|
||||||
|
-- 修订时间: 2026-02-17
|
||||||
|
-- 处理评审问题: R1, R2, I1, I2, I3(文档), L1, L2
|
||||||
|
-- ============================================================
|
||||||
|
|
||||||
|
USE pigxx_app;
|
||||||
|
SET NAMES utf8mb4;
|
||||||
|
|
||||||
|
-- ============================================================
|
||||||
|
-- R2: 修复 as_user_sub_member 唯一键问题
|
||||||
|
-- 原 UNIQUE(sub_id, user_id) 导致续费覆盖历史记录
|
||||||
|
-- 改为:允许多条记录,逻辑约束同 sub_id+user_id 只有一条 status=1
|
||||||
|
-- ============================================================
|
||||||
|
ALTER TABLE `as_user_sub_member`
|
||||||
|
DROP INDEX IF EXISTS `uk_sub_user`;
|
||||||
|
|
||||||
|
-- 补充索引(定时任务/我的订阅高频查询)
|
||||||
|
ALTER TABLE `as_user_sub_member`
|
||||||
|
ADD INDEX IF NOT EXISTS `idx_user_status` (`user_id`, `status`),
|
||||||
|
ADD INDEX IF NOT EXISTS `idx_expire_status` (`expire_time`, `status`);
|
||||||
|
|
||||||
|
-- L1: status 增加 4=等待车主录入凭据(广场拼车场景)
|
||||||
|
-- 注:仅修改注释,逻辑不变;应用层处理状态值
|
||||||
|
ALTER TABLE `as_user_sub_member`
|
||||||
|
MODIFY COLUMN `status` tinyint NOT NULL DEFAULT 0
|
||||||
|
COMMENT '状态: 0=待激活, 1=使用中, 2=已到期, 3=已退订, 4=等待车主录入凭据';
|
||||||
|
|
||||||
|
|
||||||
|
-- ============================================================
|
||||||
|
-- I2: as_sub_product.sub_plan_ids 逗号分隔改为关联表
|
||||||
|
-- ============================================================
|
||||||
|
|
||||||
|
-- 新增 M:N 关联表
|
||||||
|
CREATE TABLE IF NOT EXISTS `as_product_plan_rel` (
|
||||||
|
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||||
|
`product_id` bigint NOT NULL COMMENT '产品ID(→ as_sub_product.id)',
|
||||||
|
`plan_id` bigint NOT NULL COMMENT '订阅计划ID(→ as_sub_plan.id)',
|
||||||
|
`sort_order` int NOT NULL DEFAULT 0 COMMENT '排序权重(同产品内多计划的展示顺序)',
|
||||||
|
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
UNIQUE KEY `uk_product_plan` (`product_id`, `plan_id`),
|
||||||
|
KEY `idx_product_id` (`product_id`),
|
||||||
|
KEY `idx_plan_id` (`plan_id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||||
|
COMMENT='产品-订阅计划关联表(M:N)';
|
||||||
|
|
||||||
|
-- 移除旧的逗号分隔字段
|
||||||
|
ALTER TABLE `as_sub_product`
|
||||||
|
DROP COLUMN IF EXISTS `sub_plan_ids`;
|
||||||
|
|
||||||
|
-- 补充 as_sub_product 高频查询索引
|
||||||
|
ALTER TABLE `as_sub_product`
|
||||||
|
ADD INDEX IF NOT EXISTS `idx_product_type_status` (`product_type`, `status`);
|
||||||
|
|
||||||
|
|
||||||
|
-- ============================================================
|
||||||
|
-- R1: 新增 as_recharge — 钱包充值单
|
||||||
|
-- 支持外部支付充值时追踪(待支付→成功→到账)
|
||||||
|
-- ============================================================
|
||||||
|
CREATE TABLE IF NOT EXISTS `as_recharge` (
|
||||||
|
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||||
|
`recharge_no` varchar(32) NOT NULL COMMENT '充值单号(RC+时间戳+随机,业务唯一)',
|
||||||
|
`user_id` bigint NOT NULL COMMENT '用户ID(→ app_user.user_id)',
|
||||||
|
`amount` decimal(10,2) NOT NULL COMMENT '充值金额',
|
||||||
|
`pay_type` tinyint NOT NULL COMMENT '支付方式: 1=人工充值(管理员), 2=支付宝, 3=微信支付',
|
||||||
|
`pay_no` varchar(64) DEFAULT NULL COMMENT '第三方支付单号(外部支付时回填)',
|
||||||
|
`status` tinyint NOT NULL DEFAULT 0 COMMENT '状态: 0=待支付, 1=已支付/已到账, 2=支付失败, 3=已取消',
|
||||||
|
`remark` varchar(256) DEFAULT NULL COMMENT '备注(人工充值时填写原因)',
|
||||||
|
`operator_id` bigint DEFAULT NULL COMMENT '操作人ID(人工充值时为管理员ID)',
|
||||||
|
`expire_time` datetime DEFAULT NULL COMMENT '订单过期时间(外部支付时 +15min)',
|
||||||
|
`pay_time` datetime DEFAULT NULL COMMENT '实际支付/到账时间',
|
||||||
|
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||||
|
`update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
UNIQUE KEY `uk_recharge_no` (`recharge_no`),
|
||||||
|
KEY `idx_user_id` (`user_id`),
|
||||||
|
KEY `idx_status` (`status`),
|
||||||
|
KEY `idx_pay_no` (`pay_no`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||||
|
COMMENT='钱包充值单表(含外部支付追踪)';
|
||||||
|
|
||||||
|
|
||||||
|
-- ============================================================
|
||||||
|
-- I1: 新增 as_banner — 首页广告位/Banner
|
||||||
|
-- ============================================================
|
||||||
|
CREATE TABLE IF NOT EXISTS `as_banner` (
|
||||||
|
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||||
|
`title` varchar(128) NOT NULL COMMENT 'Banner 标题(后台管理用)',
|
||||||
|
`image_url` varchar(512) NOT NULL COMMENT 'Banner 图片 URL',
|
||||||
|
`link_type` tinyint NOT NULL DEFAULT 0 COMMENT '跳转类型: 0=无跳转, 1=商品详情, 2=外部链接, 3=平台分类',
|
||||||
|
`link_target` varchar(512) DEFAULT NULL COMMENT '跳转目标(商品ID/URL/分类ID,按 link_type 解析)',
|
||||||
|
`sort_order` int NOT NULL DEFAULT 0 COMMENT '排序权重(升序,值小靠前)',
|
||||||
|
`status` tinyint NOT NULL DEFAULT 0 COMMENT '状态: 0=草稿, 1=展示中, 2=已下线',
|
||||||
|
`start_time` datetime DEFAULT NULL COMMENT '展示开始时间(NULL=立即生效)',
|
||||||
|
`end_time` datetime DEFAULT NULL COMMENT '展示结束时间(NULL=长期有效)',
|
||||||
|
`create_by` varchar(64) DEFAULT NULL COMMENT '创建人',
|
||||||
|
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||||
|
`update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
KEY `idx_status_sort` (`status`, `sort_order`),
|
||||||
|
KEY `idx_time_range` (`start_time`, `end_time`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||||
|
COMMENT='首页 Banner 广告位表';
|
||||||
|
|
||||||
|
|
||||||
|
-- ============================================================
|
||||||
|
-- L2: 补充关键查询索引
|
||||||
|
-- ============================================================
|
||||||
|
|
||||||
|
-- as_order: 用户订单列表 / 状态过滤
|
||||||
|
ALTER TABLE `as_order`
|
||||||
|
ADD INDEX IF NOT EXISTS `idx_user_status` (`user_id`, `status`);
|
||||||
|
|
||||||
|
-- as_notification: 未读消息数
|
||||||
|
ALTER TABLE `as_notification`
|
||||||
|
ADD INDEX IF NOT EXISTS `idx_user_read` (`user_id`, `is_read`);
|
||||||
|
|
||||||
|
-- as_user_sub: 商品下的可用合租槽
|
||||||
|
ALTER TABLE `as_user_sub`
|
||||||
|
ADD INDEX IF NOT EXISTS `idx_product_status` (`product_id`, `status`);
|
||||||
|
|
||||||
|
-- as_sub_account: 产品下的账号列表
|
||||||
|
ALTER TABLE `as_sub_account`
|
||||||
|
ADD INDEX IF NOT EXISTS `idx_product_status` (`product_id`, `status`);
|
||||||
|
|
||||||
|
-- ============================================================
|
||||||
|
-- END
|
||||||
|
-- ============================================================
|
||||||
Reference in New Issue
Block a user