Files
pigx_ishare/DATABASE_DESIGN_OVERVIEW.md

212 lines
8.3 KiB
Markdown
Raw 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.
# iShare 数据库设计概要
> 基于 DATABASE_DESIGN_V2.md 整理
> 评审时间2026-02-17
> 完整建表 SQL`db/ishare_schema_v2.sql`
> 完整字段说明:`DATABASE_DESIGN_V2.md`
---
## 一、表总览23 张表)
### 1.1 App 基础表(复用 PigX共 9 张)
| # | 表名 | 说明 | 变更 |
|---|------|------|------|
| 1 | `app_user` | 用户 | 追加 `invite_code``inviter_id` |
| 2 | `app_role` | 角色 | 沿用 |
| 3 | `app_user_role` | 用户角色关联 | 沿用 |
| 4 | `app_social_details` | 第三方登录 | 沿用 |
| 5 | `app_article_category` | 文章分类 | 沿用 |
| 6 | `app_article` | 文章/公告 | 沿用 |
| 7 | `app_article_collect` | 文章收藏 | 沿用 |
| 8 | `app_page` | 页面配置 | 沿用 |
| 9 | `app_tabbar` | 底部导航 | 沿用 |
### 1.2 业务表iShare 专属,共 14 张)
#### 平台与产品
| # | 表名 | 说明 |
|---|------|------|
| 10 | `as_platform_type` | 平台分类(视频/音乐/AI等 |
| 11 | `as_platform` | 流媒体平台Netflix/Spotify等 |
| 12 | `as_sub_plan` | 订阅计划(高级版/家庭版等) |
| 13 | `as_sub_payroll` | 付费方案(月/季/年,含价格) |
| 14 | `as_sub_product` | 合租商品(自营 or 个人发布) |
| 15 | `as_sub_account` | 平台账号凭据AES 加密存储) |
| 16 | `as_sub_product_comment` | 商品评价 |
#### 订阅与订单
| # | 表名 | 说明 |
|---|------|------|
| 17 | `as_user_sub` | 合租槽/共享池(一个账号对应一个槽) |
| 18 | `as_user_sub_member` | 个人订阅记录(原版缺失最关键表) |
| 19 | `as_order` | 订单(含状态机、价格快照) |
#### 钱包与推广
| # | 表名 | 说明 |
|---|------|------|
| 20 | `as_wallet` | 用户钱包(乐观锁防并发) |
| 21 | `as_wallet_log` | 钱包流水(含余额快照便于对账) |
| 22 | `as_invite` | 邀请关系与返现 |
| 23 | `as_notification` | 系统通知(续费提醒/订单/公告/奖励) |
---
## 二、核心 ER 关系概览
```
as_platform_type (1) ──< (N) as_platform
as_platform (1) ──< (N) as_sub_plan
as_sub_plan (1) ──< (N) as_sub_payroll
as_sub_plan (N) >──< (N) as_sub_product ← sub_plan_ids 逗号分隔(待决策改关联表)
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_user_sub [product_id]
as_user_sub (1) ──< (N) as_user_sub_member [sub_id] ← 新增关键关联
as_sub_product (1) ──< (N) as_order [product_id]
as_order (1) ──< (1) as_user_sub_member [order_id]
app_user (1) ──< (1) as_wallet
as_wallet (1) ──< (N) as_wallet_log
app_user (1) ──< (N) as_order
app_user (1) ──< (N) as_user_sub_member
app_user (1) ──< (N) as_invite [as inviter]
app_user (1) ──< (1) as_invite [as invitee]
app_user (1) ──< (N) as_notification
```
---
## 三、关键状态机
### 3.1 订单as_order
```
[待支付] ─→ 15min 超时 ─→ [已取消]
[待支付] ─→ 支付成功 ─→ [已支付] ─→ 激活订阅 ─→ [已完成]
[已支付/已完成] ─→ 退款 ─→ [已退款]
```
### 3.2 个人订阅as_user_sub_member
```
[待激活] ─→ 订单完成 ─→ [使用中]
├─→ 到期 ─→ [已到期] ─→ 续费 ─→ [使用中]
└─→ 主动退订 ─→ [已退订]
```
### 3.3 合租槽as_user_sub
```
[可加入(0)] ─→ 席位满(capacity_loaded = capacity) ─→ [已满(1)]
[可加入/已满] ─→ 到期 ─→ [已到期(2)]
[可加入/已满] ─→ 车主关闭 ─→ [已关闭(3)]
```
---
## 四、关键设计机制
### 4.1 席位超卖防护(乐观锁)
```sql
-- 购买时原子性占位row affected = 0 则席位已满
UPDATE as_user_sub
SET capacity_loaded = capacity_loaded + 1
WHERE id = ? AND capacity_loaded < capacity
```
### 4.2 账号凭据加密
- 算法AES-256-GCM`as_sub_account.encrypt_type = 1`
- `account_passwd`密文Base64
- `passwd_salt`:随机 IV16 字节 Base64**原设计为 int 已修复**
- 密钥:服务端环境变量,不入库
- 查看凭据:仅限 `as_user_sub_member.status = 1使用中`,服务端解密后返回明文,不记录日志
### 4.3 钱包余额并发控制(乐观锁)
```sql
UPDATE as_wallet
SET balance = balance - ?, version = version + 1
WHERE user_id = ? AND version = ? AND balance >= ?
-- row affected = 0并发冲突或余额不足
```
### 4.4 订阅到期定时任务(建议每日 02:00
```
1. expire_time < now() + 7天 且 status=1 → 推送续费提醒通知
2. expire_time < now() 且 status=1 → 标记 status=2已到期
→ as_user_sub.capacity_loaded -1释放席位
```
---
## 五、设计评审问题清单
> 评审时间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
-- 我的订阅列表
CREATE INDEX idx_member_user_status ON as_user_sub_member(user_id, status);
-- 定时任务扫描到期
CREATE INDEX idx_member_expire ON as_user_sub_member(expire_time, status);
-- 用户订单列表
CREATE INDEX idx_order_user_status ON as_order(user_id, status);
-- 订单号查询(已设 UNIQUE跳过
-- 未读通知数
CREATE INDEX idx_notif_user_read ON as_notification(user_id, is_read);
-- 合租槽状态
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);
```
---
## 六、待决策项(需 Ami 确认)
| # | 问题 | 选项 |
|---|------|------|
| 1 | 付费方式一期支持哪些? | A) 仅余额人工充值B) 余额+支付宝 C) 三种都支持 |
| 2 | 拼车广场是否需要审核流程? | A) 管理员审核 B) 自动上架 C) 仅自营,无拼车广场 |
| 3 | 账号凭据展示方式? | A) 直接明文 B) 需二次验证(短信/密码C) 限时展示30s后隐藏|
| 4 | 邀请返现比例和条件? | 需定义:返现金额/比例,是否有上限 |
| 5 | `as_sub_product` 的多计划关联是否改为关联表? | A) 保持逗号分隔 B) 改关联表(**推荐**,趁现在改成本最低)|
| 6 | 提现功能是否一期上线? | A) 一期上 B) 二期(一期只充值不提现)|
---
*文档由 AI 评审生成 · 最后更新2026-02-17*