312 lines
16 KiB
Markdown
312 lines
16 KiB
Markdown
## 数据分析模块数据库设计(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` 的表/视图;复杂统计使用 **RPC(Postgres 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-100)或(0-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 未参考任何实现代码的声明
|
||
本文档的表结构与字段设计为**基于可观察页面字段与需求规格独立推导**的原创设计,未复制/改写任何第三方或原项目实现源码。
|
||
|