## 数据分析模块数据库设计(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
```
**调用 RPC 获取实时 KPI**:
```vue
```
---
## 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 未参考任何实现代码的声明
本文档的表结构与字段设计为**基于可观察页面字段与需求规格独立推导**的原创设计,未复制/改写任何第三方或原项目实现源码。