Files
medical-mall/pages/mall/analytics/docs/ANALYTICS_DB_DESIGN.md
2026-01-23 16:33:11 +08:00

312 lines
16 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.
## 数据分析模块数据库设计Supabase / Postgres
> 本文档面向 **数据分析端Analytics Dashboard**,为页面 `pages/mall/analytics/*` 提供可落地的表结构、字段字典、以及用于联调的模拟数据方案。
>
> 参考输入(仅作为需求与既有模型依据):`pages/mall/mall.md`(订单/用户/商品/配送/优惠券/统计)、`pages/mall/analytics/docs/ANALYTICS_PAGES_ANALYSIS.md`(页面与指标清单)、以及前端页面当前使用的字段名(如 `realTime.gmv`、`report.title` 等)。
>
> **文档位置**`pages/mall/analytics/docs/ANALYTICS_DB_DESIGN.md`
---
## 1. 设计目标与范围
### 1.1 目标
- **支持已实现页面的数据落库**`index`(实时 KPI + 趋势)、`profile`(报表列表/偏好/导出)、`report-detail`(报表详情 + 指标 + 明细表格 + 洞察)。
- **支持后续页面扩展**`sales-report``user-analysis``product-insights``delivery-analysis``coupon-analysis``market-trends``custom-report`
- **与 `components/supadb` 兼容**:优先提供可 `select` 的表/视图;复杂统计使用 **RPCPostgres function**,在前端通过 `supadb.uvue``rpc` 能力调用。
### 1.2 范围说明
- 本文档**不替代**业务核心表(如 `orders``order_items``products``users``delivery_tasks``coupon_*`)。这些以 `pages/mall/mall.md` 为准。
- 本文档新增的是 **Analytics 侧“报表/洞察/导出/偏好/预警”等应用数据表**,以及可选的聚合视图/RPC。
---
## 2. 现有基础表(业务域)与分析端关系
数据分析端统计大多来源于以下基础表(来自 `mall.md` 的模型):
- **订单域**`orders``order_items`
- **用户域**`users`
- **商家/商品域**`merchants``products``categories`
- **配送域**`delivery_tasks``delivery_drivers``delivery_tracks`
- **营销域**`coupon_templates``user_coupons``coupon_usage_logs`
- **统计域(已在需求中出现)**`daily_statistics`(按天、可按 `merchant_id` 聚合)
分析端新增的表会通过外键关联这些基础表(尤其是 `users``merchants``orders`)。
---
## 3. Analytics 新增表:数据字典(推荐最小集)
> 命名约定:以 `analytics_` 为前缀,避免与业务表冲突。
### 3.1 `analytics_user_preferences`(分析师偏好)
**用途**`profile` 页偏好设置、默认周期、默认看板等。
| 字段 | 类型 | 约束 | 说明 |
| -------------- | ----------- | ----------------------- | ------------------------- |
| id | uuid | PK | 主键 |
| user_id | uuid | FK → users(id), UNIQUE | 偏好所属用户 |
| default_period | text | NOT NULL, default '7d' | 7d/30d/90d/1y 等 |
| timezone | text | default 'Asia/Shanghai' | 时区 |
| currency | text | default 'CNY' | 展示币种 |
| kpi_cards | jsonb | default '[]' | KPI 卡片配置(顺序/开关) |
| created_at | timestamptz | default now() | 创建时间 |
| updated_at | timestamptz | default now() | 更新时间 |
索引建议:`(user_id)` 唯一索引即可。
---
### 3.2 `analytics_reports`(报表定义/实例)
**用途**`report-detail` 的 report 主体、`profile` 最近报表列表、`custom-report` 报表定义。
| 字段 | 类型 | 约束 | 说明 |
| ------------- | ----------- | ---------------------------- | -------------------------------------------------------------- |
| id | uuid | PK | 报表 ID |
| owner_user_id | uuid | FK → users(id) | 报表创建者/所属分析师 |
| merchant_id | uuid | FK → merchants(id), nullable | 可选:报表限定商家 |
| title | text | NOT NULL | 报表标题(`report.title` |
| description | text | default '' | 描述(列表展示) |
| type | text | NOT NULL | sales/users/orders/conversion/coupon/delivery/market/custom 等 |
| period | text | NOT NULL | 7d/30d/90d/1y 或自定义 |
| date_start | date | nullable | 自定义范围起始 |
| date_end | date | nullable | 自定义范围结束 |
| status | text | NOT NULL, default 'ready' | pending/ready/failed/scheduled/shared |
| generated_at | timestamptz | nullable | 生成时间(`report.generated_at` |
| created_at | timestamptz | default now() | 创建时间 |
| updated_at | timestamptz | default now() | 更新时间 |
索引建议:
- `(owner_user_id, created_at desc)`
- `(type, generated_at desc)`
- `(status)`
---
### 3.3 `analytics_report_metrics`(报表核心指标)
**用途**`report-detail` 页“核心指标”网格(`coreMetrics`)。
| 字段 | 类型 | 约束 | 说明 |
| ----------------- | ----------- | -------------------------- | ---------------------------------------------- |
| id | uuid | PK | 主键 |
| report_id | uuid | FK → analytics_reports(id) | 所属报表 |
| metric_key | text | NOT NULL | gmv/orders/conversion_rate/avg_order_amount 等 |
| metric_label | text | NOT NULL | 展示名称 |
| metric_value_num | numeric | nullable | 数值 |
| metric_value_text | text | nullable | 文本(如百分比已格式化) |
| format | text | NOT NULL, default 'number' | number/currency/percent |
| change_pct | numeric | default 0 | 环比/同比变化(页面用 `metric.change` |
| icon | text | default '' | UI 图标(可选) |
| color | text | default '#3b82f6' | UI 颜色(可选) |
| created_at | timestamptz | default now() | 创建时间 |
索引建议:`(report_id, metric_key)` 唯一或普通索引(按需求)。
---
### 3.4 `analytics_report_rows`(报表明细表格/趋势表)
**用途**`report-detail` 页“详细数据”表格与趋势(`tableData`、图表)。
| 字段 | 类型 | 约束 | 说明 |
| ---------------- | ----------- | -------------------------- | ---------------------------------- |
| id | uuid | PK | 主键 |
| report_id | uuid | FK → analytics_reports(id) | 所属报表 |
| row_date | date | NOT NULL | 统计日期(或维度日期) |
| gmv | numeric | default 0 | GMV |
| orders | integer | default 0 | 订单数 |
| users | integer | default 0 | 用户数(可选) |
| conversion | numeric | default 0 | 转化率0-1000-1需统一约定 |
| avg_order_amount | numeric | default 0 | 客单价 |
| extra | jsonb | default '{}' | 扩展字段(用于自定义报表列) |
| created_at | timestamptz | default now() | 创建时间 |
索引建议:
- `(report_id, row_date)`
---
### 3.5 `analytics_insights`(洞察/建议)
**用途**`profile` 今日洞察、`report-detail` 洞察列表、`insight-detail` 详情页。
| 字段 | 类型 | 约束 | 说明 |
| ------------- | ----------- | ------------------------------------ | --------------------------------- |
| id | uuid | PK | 洞察 ID |
| report_id | uuid | FK → analytics_reports(id), nullable | 关联报表(可空:全局洞察) |
| owner_user_id | uuid | FK → users(id), nullable | 关联分析师(可空:系统生成) |
| type | text | NOT NULL | positive/warning/negative/info 等 |
| impact | text | NOT NULL, default 'medium' | high/medium/low |
| title | text | NOT NULL | 洞察标题 |
| content | text | NOT NULL | 洞察内容 |
| tags | text[] | default '{}' | 标签(可选) |
| created_at | timestamptz | default now() | 创建时间 |
索引建议:
- `(created_at desc)`
- `(report_id, created_at desc)`
---
### 3.6 `analytics_report_favorites`(收藏/快捷入口)
**用途**`profile` 报表收藏管理。
| 字段 | 类型 | 约束 | 说明 |
| ---------- | ----------- | -------------------------- | -------- |
| id | uuid | PK | 主键 |
| user_id | uuid | FK → users(id) | 用户 |
| report_id | uuid | FK → analytics_reports(id) | 报表 |
| created_at | timestamptz | default now() | 创建时间 |
唯一约束:`UNIQUE(user_id, report_id)`
---
### 3.7 `analytics_export_jobs`(导出任务/历史)
**用途**`profile` 导出历史、`report-detail` 导出按钮触发。
| 字段 | 类型 | 约束 | 说明 |
| ------------- | ----------- | -------------------------- | -------------------------- |
| id | uuid | PK | 导出任务 ID |
| user_id | uuid | FK → users(id) | 发起用户 |
| report_id | uuid | FK → analytics_reports(id) | 关联报表 |
| format | text | NOT NULL | csv/xlsx/pdf/json |
| status | text | NOT NULL, default 'queued' | queued/running/done/failed |
| file_path | text | nullable | Storage 路径(私有桶) |
| error_message | text | default '' | 失败原因 |
| created_at | timestamptz | default now() | 创建时间 |
| finished_at | timestamptz | nullable | 完成时间 |
索引建议:`(user_id, created_at desc)``(status)`
---
## 4. 可选:视图与 RPC推荐
### 4.1 视图:`v_analytics_daily_overview`
**用途**:复用 `daily_statistics`,快速给首页 KPI 与趋势提供数据源。
- 粒度:按 `stat_date` + `merchant_id`(或全站 merchant_id 为空/特殊值)
> 是否需要全站维度:建议 **用 `merchant_id` 为空表示全站** 或单独建全站行。
### 4.2 RPC`rpc_analytics_realtime_kpis`
**用途**:首页实时 KPI对比昨日同刻
输入建议:
- `p_start timestamptz`:今日起始
- `p_end timestamptz`:今日结束(当前时间)
- `p_compare_start timestamptz`:昨日对应起始
- `p_compare_end timestamptz`:昨日对应结束
- `p_merchant_id uuid`(可选)
输出建议(单行):
- `gmv, gmv_growth, orders, order_growth, online_users, conversion_rate, conversion_growth`
> 前端当前 `index.uvue` 直接从 `orders` 表计算 KPI后续可以改为 RPC 提升性能与一致性。
---
## 5. RLS权限矩阵建议
> 核心原则:前端只用 anon key所有访问靠 RLS。
### 5.1 表访问建议
- `analytics_user_preferences`:用户只能读写自己的 `user_id = auth.uid()`
- `analytics_reports`
- 普通分析师:`owner_user_id = auth.uid()` 的报表可读写
- 共享报表:`status = 'shared'` 可读(可加 share 表细化)
- `analytics_report_metrics` / `analytics_report_rows` / `analytics_insights` / `analytics_export_jobs`:通过关联 `report_id``user_id` 做同权限继承
---
## 6. 模拟数据(联调)策略
**目标**:让下列页面在无真实业务数据时也能跑通:
- `index`:订单与用户有数据 → KPI 与趋势能算出来
- `profile`:有“最近报表/洞察/导出任务”列表
- `report-detail`:存在 `analytics_reports` + `metrics` + `rows` + `insights`
### 6.1 推荐做法
- 插入少量 `users/merchants/products/orders/order_items`(过去 30 天)
- 同时插入 2-3 份 `analytics_reports`(不同 type/period
- 每份报表插入 4-6 个核心指标 + 15-30 行 `analytics_report_rows`
- 插入 3-8 条 `analytics_insights`
- 插入 2-3 条 `analytics_export_jobs`
对应 SQL 脚本(位于 `pages/mall/analytics/test/` 目录):
- **Schema表结构/索引/RLS/RPC**`pages/mall/analytics/test/ANALYTICS_DB_SCHEMA.sql`
- **测试数据Seed**`pages/mall/analytics/test/ANALYTICS_TEST_SEED.sql`
- **分步执行脚本**
- `01_create_tables.sql` - 创建表结构
- `02_insert_test_data.sql` - 插入测试数据
- `03_test_queries.sql` - 测试查询示例
- `04_cleanup.sql` - 清理测试数据
- **使用指南**`pages/mall/analytics/test/README.md``SQL_USAGE_GUIDE.md`
---
## 7. 使用说明
### 7.1 部署步骤
1. **执行 Schema**创建表、索引、RLS、RPC
```sql
-- 在 Supabase SQL Editor 中执行
-- 方式一:直接复制粘贴 ANALYTICS_DB_SCHEMA.sql 内容
-- 方式二:使用分步脚本(推荐)
\i pages/mall/analytics/test/01_create_tables.sql
```
2. **插入测试数据**
```sql
-- 方式一:直接复制粘贴 ANALYTICS_TEST_SEED.sql 内容
-- 方式二:使用分步脚本(推荐)
\i pages/mall/analytics/test/02_insert_test_data.sql
```
3. **验证查询**(可选):
```sql
\i pages/mall/analytics/test/03_test_queries.sql
```
3. **验证**
- 检查表是否创建:`SELECT * FROM analytics_reports LIMIT 1;`
- 检查 RPC 是否可用:`SELECT * FROM rpc_analytics_realtime_kpis(...);`
### 7.2 前端调用示例(使用 `components/supadb`
**查询报表列表**
```vue
<supadb
collection="analytics_reports"
:filter="{ owner_user_id: currentUserId }"
orderby="created_at desc"
:pageSize="10"
/>
```
**调用 RPC 获取实时 KPI**
```vue
<supadb
rpc="rpc_analytics_realtime_kpis"
:params="{
p_start: todayStart,
p_end: now,
p_compare_start: yesterdayStart,
p_compare_end: yesterdaySameTime,
p_merchant_id: null
}"
getone
/>
```
---
## 8. 反抄袭自证
### 8.1 仅参考资料(只含规范/文档/API
- `pages/mall/mall.md`(项目需求与数据模型)
- `pages/mall/analytics/docs/ANALYTICS_PAGES_ANALYSIS.md`(页面与指标清单)
- `pages/mall/analytics/docs/ANALYTICS_UI_DESIGN.md`(页面与交互约定)
- Supabase/Postgres 官方文档(表/索引/RLS/RPC 概念)
### 8.2 未参考任何实现代码的声明
本文档的表结构与字段设计为**基于可观察页面字段与需求规格独立推导**的原创设计,未复制/改写任何第三方或原项目实现源码。