rwadurian/backend/services/reporting-service/docs/DATA-MODEL.md

681 lines
22 KiB
Markdown

# 数据模型文档
## 1. 数据模型概述
### 1.1 实体关系图 (ER Diagram)
```
┌─────────────────────┐
│ ReportDefinition │
│ (报表定义) │
│ ───────────────── │
│ definition_id PK │
│ report_code UK │
│ report_type │
│ report_name │
│ parameters JSON │
│ schedule_cron │
│ output_formats[] │
└─────────────────────┘
┌─────────────────────┐ ┌─────────────────────┐
│ ReportSnapshot │ 1───n │ ReportFile │
│ (报表快照) │ │ (报表文件) │
│ ───────────────── │ │ ───────────────── │
│ snapshot_id PK │ │ file_id PK │
│ report_code │ │ snapshot_id FK │
│ report_period │ │ file_name │
│ period_key UK(c) │ │ file_path │
│ snapshot_data JSON │ │ file_format │
│ summary_data JSON │ │ file_size │
└─────────────────────┘ └─────────────────────┘
┌─────────────────────┐ ┌─────────────────────┐
│ AnalyticsMetric │ │ PlantingDailyStat │
│ (分析指标) │ │ (认种日统计) │
│ ───────────────── │ │ ───────────────── │
│ metric_id PK │ │ stat_id PK │
│ metric_type │ │ stat_date │
│ metric_code │ │ province_code │
│ dimension_time │ │ city_code │
│ metric_value DEC │ │ order_count │
│ metric_data JSON │ │ total_amount DEC │
└─────────────────────┘ └─────────────────────┘
┌─────────────────────┐ ┌──────────────────────────┐
│ CommunityStat │ │ SystemAccountMonthlyStat │
│ (社区统计) │ │ (系统账户月度统计) │
│ ───────────────── │ │ ───────────────────── │
│ stat_id PK │ │ stat_id PK │
│ community_id │ │ account_id │
│ community_name │ │ account_type │
│ stat_date │ │ stat_month │
│ total_planting │ │ monthly_hashpower DEC │
│ member_count │ │ cumulative_mining DEC │
└─────────────────────┘ └──────────────────────────┘
┌──────────────────────────┐ ┌─────────────────────┐
│ SystemAccountIncomeRecord│ │ ReportEvent │
│ (系统账户收益流水) │ │ (报表事件) │
│ ───────────────────── │ │ ───────────────── │
│ record_id PK │ │ event_id PK │
│ account_id │ │ event_type │
│ income_type │ │ aggregate_id │
│ income_amount DEC │ │ aggregate_type │
│ source_type │ │ event_data JSON │
│ occurred_at │ │ occurred_at │
└──────────────────────────┘ └─────────────────────┘
```
### 1.2 聚合根划分
| 聚合根 | 表 | 说明 |
|--------|-----|------|
| ReportDefinition | report_definitions | 报表定义,包含配置和调度规则 |
| ReportSnapshot | report_snapshots, report_files | 报表快照,包含生成的文件 |
| AnalyticsMetric | analytics_metrics | 独立的分析指标聚合 |
## 2. 核心表结构
### 2.1 ReportDefinition (报表定义表)
```sql
CREATE TABLE report_definitions (
definition_id BIGSERIAL PRIMARY KEY,
-- 报表基本信息
report_type VARCHAR(50) NOT NULL,
report_name VARCHAR(200) NOT NULL,
report_code VARCHAR(50) NOT NULL UNIQUE,
description TEXT,
-- 报表参数 (JSON)
parameters JSONB NOT NULL DEFAULT '{}',
-- 调度配置
schedule_cron VARCHAR(100),
schedule_timezone VARCHAR(50) DEFAULT 'Asia/Shanghai',
schedule_enabled BOOLEAN DEFAULT FALSE,
-- 输出格式
output_formats VARCHAR(20)[] NOT NULL DEFAULT '{}',
-- 状态
is_active BOOLEAN DEFAULT TRUE,
-- 时间戳
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW(),
last_generated_at TIMESTAMP
);
-- 索引
CREATE INDEX idx_def_type ON report_definitions(report_type);
CREATE INDEX idx_def_active ON report_definitions(is_active);
CREATE INDEX idx_def_scheduled ON report_definitions(schedule_enabled);
```
**字段说明:**
| 字段 | 类型 | 说明 |
|------|------|------|
| definition_id | BIGSERIAL | 主键,自增ID |
| report_type | VARCHAR(50) | 报表类型: LEADERBOARD, PLANTING, ANALYTICS 等 |
| report_name | VARCHAR(200) | 报表显示名称 |
| report_code | VARCHAR(50) | 报表唯一编码,用于API调用 |
| description | TEXT | 报表描述说明 |
| parameters | JSONB | 报表参数配置 |
| schedule_cron | VARCHAR(100) | Cron 表达式,定时生成 |
| schedule_timezone | VARCHAR(50) | 调度时区 |
| schedule_enabled | BOOLEAN | 是否启用定时生成 |
| output_formats | VARCHAR(20)[] | 支持的输出格式数组 |
| is_active | BOOLEAN | 是否激活 |
| last_generated_at | TIMESTAMP | 最后生成时间 |
**parameters JSON 结构示例:**
```json
{
"dataSource": "leaderboard_rankings",
"aggregation": "daily",
"filters": {
"regionLevel": "province",
"minScore": 100
},
"columns": [
{ "field": "rank", "label": "排名" },
{ "field": "userName", "label": "用户名" },
{ "field": "score", "label": "积分" }
]
}
```
### 2.2 ReportSnapshot (报表快照表)
```sql
CREATE TABLE report_snapshots (
snapshot_id BIGSERIAL PRIMARY KEY,
-- 报表信息
report_type VARCHAR(50) NOT NULL,
report_code VARCHAR(50) NOT NULL,
report_period VARCHAR(20) NOT NULL,
period_key VARCHAR(30) NOT NULL,
-- 快照数据
snapshot_data JSONB NOT NULL,
summary_data JSONB,
-- 数据来源
data_sources VARCHAR(100)[] DEFAULT '{}',
data_freshness INTEGER DEFAULT 0,
-- 过滤条件
filter_params JSONB,
-- 统计信息
row_count INTEGER DEFAULT 0,
-- 时间范围
period_start_at TIMESTAMP NOT NULL,
period_end_at TIMESTAMP NOT NULL,
-- 时间戳
generated_at TIMESTAMP DEFAULT NOW(),
expires_at TIMESTAMP,
UNIQUE(report_code, period_key)
);
-- 索引
CREATE INDEX idx_snapshot_type ON report_snapshots(report_type);
CREATE INDEX idx_snapshot_code ON report_snapshots(report_code);
CREATE INDEX idx_snapshot_period ON report_snapshots(period_key);
CREATE INDEX idx_snapshot_generated ON report_snapshots(generated_at DESC);
CREATE INDEX idx_snapshot_expires ON report_snapshots(expires_at);
```
**字段说明:**
| 字段 | 类型 | 说明 |
|------|------|------|
| snapshot_id | BIGSERIAL | 主键 |
| report_type | VARCHAR(50) | 报表类型 |
| report_code | VARCHAR(50) | 报表编码 |
| report_period | VARCHAR(20) | 报表周期: DAILY, WEEKLY, MONTHLY, YEARLY |
| period_key | VARCHAR(30) | 周期标识: 2024-01-15, 2024-W03, 2024-01 |
| snapshot_data | JSONB | 报表数据内容 |
| summary_data | JSONB | 汇总数据 |
| data_sources | VARCHAR(100)[] | 数据来源服务列表 |
| data_freshness | INTEGER | 数据新鲜度(秒) |
| filter_params | JSONB | 应用的过滤参数 |
| row_count | INTEGER | 数据行数 |
| period_start_at | TIMESTAMP | 周期开始时间 |
| period_end_at | TIMESTAMP | 周期结束时间 |
| generated_at | TIMESTAMP | 生成时间 |
| expires_at | TIMESTAMP | 过期时间 |
**snapshot_data JSON 结构示例:**
```json
{
"items": [
{
"rank": 1,
"userId": "12345",
"userName": "张三",
"score": 9850,
"treeCount": 100,
"region": "广东省"
}
],
"metadata": {
"totalRecords": 1000,
"generatedAt": "2024-01-15T08:00:00Z",
"version": "1.0"
}
}
```
### 2.3 ReportFile (报表文件表)
```sql
CREATE TABLE report_files (
file_id BIGSERIAL PRIMARY KEY,
snapshot_id BIGINT NOT NULL REFERENCES report_snapshots(snapshot_id) ON DELETE CASCADE,
-- 文件信息
file_name VARCHAR(500) NOT NULL,
file_path VARCHAR(1000) NOT NULL,
file_url VARCHAR(1000),
file_size BIGINT NOT NULL,
file_format VARCHAR(20) NOT NULL,
mime_type VARCHAR(100) NOT NULL,
-- 访问信息
download_count INTEGER DEFAULT 0,
last_download_at TIMESTAMP,
-- 时间戳
created_at TIMESTAMP DEFAULT NOW(),
expires_at TIMESTAMP
);
-- 索引
CREATE INDEX idx_file_snapshot ON report_files(snapshot_id);
CREATE INDEX idx_file_format ON report_files(file_format);
CREATE INDEX idx_file_created ON report_files(created_at DESC);
```
**字段说明:**
| 字段 | 类型 | 说明 |
|------|------|------|
| file_id | BIGSERIAL | 主键 |
| snapshot_id | BIGINT | 关联的快照ID |
| file_name | VARCHAR(500) | 文件名 |
| file_path | VARCHAR(1000) | 文件存储路径 |
| file_url | VARCHAR(1000) | 文件下载URL |
| file_size | BIGINT | 文件大小(字节) |
| file_format | VARCHAR(20) | 文件格式: EXCEL, CSV, PDF |
| mime_type | VARCHAR(100) | MIME类型 |
| download_count | INTEGER | 下载次数 |
| last_download_at | TIMESTAMP | 最后下载时间 |
### 2.4 AnalyticsMetric (分析指标表)
```sql
CREATE TABLE analytics_metrics (
metric_id BIGSERIAL PRIMARY KEY,
-- 指标信息
metric_type VARCHAR(50) NOT NULL,
metric_code VARCHAR(50) NOT NULL,
-- 维度
dimension_time DATE,
dimension_region VARCHAR(100),
dimension_user_type VARCHAR(50),
dimension_right_type VARCHAR(50),
-- 指标值
metric_value DECIMAL(20, 8) NOT NULL,
metric_data JSONB,
-- 时间戳
calculated_at TIMESTAMP DEFAULT NOW(),
UNIQUE(metric_code, dimension_time, dimension_region, dimension_user_type, dimension_right_type)
);
-- 索引
CREATE INDEX idx_metric_type ON analytics_metrics(metric_type);
CREATE INDEX idx_metric_code ON analytics_metrics(metric_code);
CREATE INDEX idx_metric_time ON analytics_metrics(dimension_time);
CREATE INDEX idx_metric_region ON analytics_metrics(dimension_region);
```
**指标类型 (metric_type):**
| 类型 | 说明 |
|------|------|
| PLANTING_COUNT | 认种数量 |
| PLANTING_AMOUNT | 认种金额 |
| USER_ACTIVE | 活跃用户数 |
| REVENUE_TOTAL | 总收益 |
| HASHPOWER_DAILY | 日算力 |
## 3. 统计表结构
### 3.1 PlantingDailyStat (认种日统计表)
```sql
CREATE TABLE planting_daily_stats (
stat_id BIGSERIAL PRIMARY KEY,
-- 统计日期
stat_date DATE NOT NULL,
-- 区域维度
province_code VARCHAR(10),
city_code VARCHAR(10),
-- 统计数据
order_count INTEGER DEFAULT 0,
tree_count INTEGER DEFAULT 0,
total_amount DECIMAL(20, 8) DEFAULT 0,
new_user_count INTEGER DEFAULT 0,
active_user_count INTEGER DEFAULT 0,
-- 时间戳
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW(),
UNIQUE(stat_date, province_code, city_code)
);
-- 索引
CREATE INDEX idx_pds_date ON planting_daily_stats(stat_date);
CREATE INDEX idx_pds_province ON planting_daily_stats(province_code);
CREATE INDEX idx_pds_city ON planting_daily_stats(city_code);
```
### 3.2 CommunityStat (社区统计表)
```sql
CREATE TABLE community_stats (
stat_id BIGSERIAL PRIMARY KEY,
-- 社区信息
community_id BIGINT NOT NULL,
community_name VARCHAR(200) NOT NULL,
parent_community_id BIGINT,
-- 统计日期
stat_date DATE NOT NULL,
-- 统计数据
total_planting INTEGER DEFAULT 0,
daily_planting INTEGER DEFAULT 0,
weekly_planting INTEGER DEFAULT 0,
monthly_planting INTEGER DEFAULT 0,
member_count INTEGER DEFAULT 0,
-- 时间戳
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW(),
UNIQUE(community_id, stat_date)
);
-- 索引
CREATE INDEX idx_cs_community ON community_stats(community_id);
CREATE INDEX idx_cs_name ON community_stats(community_name);
CREATE INDEX idx_cs_date ON community_stats(stat_date);
CREATE INDEX idx_cs_parent ON community_stats(parent_community_id);
```
### 3.3 SystemAccountMonthlyStat (系统账户月度统计表)
```sql
CREATE TABLE system_account_monthly_stats (
stat_id BIGSERIAL PRIMARY KEY,
-- 账户信息
account_id BIGINT NOT NULL,
account_type VARCHAR(30) NOT NULL,
account_name VARCHAR(200) NOT NULL,
region_code VARCHAR(10) NOT NULL,
-- 统计月份
stat_month VARCHAR(7) NOT NULL, -- 格式: YYYY-MM
-- 月度数据
monthly_hashpower DECIMAL(20, 8) DEFAULT 0,
cumulative_hashpower DECIMAL(20, 8) DEFAULT 0,
monthly_mining DECIMAL(20, 8) DEFAULT 0,
cumulative_mining DECIMAL(20, 8) DEFAULT 0,
monthly_commission DECIMAL(20, 8) DEFAULT 0,
cumulative_commission DECIMAL(20, 8) DEFAULT 0,
monthly_planting_bonus DECIMAL(20, 8) DEFAULT 0,
cumulative_planting_bonus DECIMAL(20, 8) DEFAULT 0,
-- 时间戳
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW(),
UNIQUE(account_id, stat_month)
);
-- 索引
CREATE INDEX idx_sams_type ON system_account_monthly_stats(account_type);
CREATE INDEX idx_sams_month ON system_account_monthly_stats(stat_month);
CREATE INDEX idx_sams_region ON system_account_monthly_stats(region_code);
```
**account_type 枚举值:**
| 值 | 说明 |
|-----|------|
| PROVINCE_COMPANY | 省公司账户 |
| CITY_COMPANY | 市公司账户 |
| PLATFORM | 平台账户 |
### 3.4 SystemAccountIncomeRecord (系统账户收益流水表)
```sql
CREATE TABLE system_account_income_records (
record_id BIGSERIAL PRIMARY KEY,
-- 账户信息
account_id BIGINT NOT NULL,
account_type VARCHAR(30) NOT NULL,
-- 收益信息
income_type VARCHAR(50) NOT NULL,
income_amount DECIMAL(20, 8) NOT NULL,
currency VARCHAR(10) NOT NULL,
-- 来源信息
source_type VARCHAR(50) NOT NULL,
source_id VARCHAR(100),
source_user_id BIGINT,
source_address VARCHAR(200),
transaction_no VARCHAR(100),
-- 备注
memo TEXT,
-- 时间戳
occurred_at TIMESTAMP NOT NULL,
created_at TIMESTAMP DEFAULT NOW()
);
-- 索引
CREATE INDEX idx_sair_account ON system_account_income_records(account_id);
CREATE INDEX idx_sair_type ON system_account_income_records(account_type);
CREATE INDEX idx_sair_income_type ON system_account_income_records(income_type);
CREATE INDEX idx_sair_source_type ON system_account_income_records(source_type);
CREATE INDEX idx_sair_address ON system_account_income_records(source_address);
CREATE INDEX idx_sair_txno ON system_account_income_records(transaction_no);
CREATE INDEX idx_sair_occurred ON system_account_income_records(occurred_at DESC);
```
**income_type 枚举值:**
| 值 | 说明 |
|-----|------|
| MINING_REWARD | 挖矿奖励 |
| COMMISSION | 佣金收入 |
| PLANTING_BONUS | 认种奖励 |
| REFERRAL_BONUS | 推荐奖励 |
**source_type 枚举值:**
| 值 | 说明 |
|-----|------|
| PLANTING_ORDER | 认种订单 |
| MINING_SETTLEMENT | 挖矿结算 |
| COMMISSION_SETTLEMENT | 佣金结算 |
| MANUAL_ADJUSTMENT | 手工调整 |
## 4. 事件表
### 4.1 ReportEvent (报表事件表)
```sql
CREATE TABLE report_events (
event_id BIGSERIAL PRIMARY KEY,
event_type VARCHAR(50) NOT NULL,
-- 聚合根信息
aggregate_id VARCHAR(100) NOT NULL,
aggregate_type VARCHAR(50) NOT NULL,
-- 事件数据
event_data JSONB NOT NULL,
-- 元数据
user_id BIGINT,
occurred_at TIMESTAMP(6) DEFAULT NOW(),
version INTEGER DEFAULT 1
);
-- 索引
CREATE INDEX idx_report_event_aggregate ON report_events(aggregate_type, aggregate_id);
CREATE INDEX idx_report_event_type ON report_events(event_type);
CREATE INDEX idx_report_event_occurred ON report_events(occurred_at);
```
**event_type 枚举值:**
| 值 | 说明 |
|-----|------|
| REPORT_DEFINITION_CREATED | 报表定义创建 |
| REPORT_DEFINITION_UPDATED | 报表定义更新 |
| REPORT_SNAPSHOT_GENERATED | 报表快照生成 |
| REPORT_FILE_EXPORTED | 报表文件导出 |
| REPORT_FILE_DOWNLOADED | 报表文件下载 |
**event_data 示例:**
```json
{
"snapshotId": "12345",
"reportCode": "RPT_LEADERBOARD",
"period": "DAILY",
"periodKey": "2024-01-15",
"rowCount": 1000,
"generatedAt": "2024-01-15T08:00:00Z"
}
```
## 5. 数据字典
### 5.1 报表周期 (ReportPeriod)
| 值 | 说明 | period_key 格式 |
|-----|------|----------------|
| DAILY | 日报 | 2024-01-15 |
| WEEKLY | 周报 | 2024-W03 |
| MONTHLY | 月报 | 2024-01 |
| YEARLY | 年报 | 2024 |
| CUSTOM | 自定义 | 2024-01-01_2024-01-31 |
### 5.2 导出格式 (ExportFormat)
| 值 | MIME类型 | 说明 |
|-----|----------|------|
| EXCEL | application/vnd.openxmlformats-officedocument.spreadsheetml.sheet | Excel 2007+ |
| CSV | text/csv | 逗号分隔值 |
| PDF | application/pdf | PDF 文档 |
| JSON | application/json | JSON 格式 |
### 5.3 报表类型 (ReportType)
| 值 | 说明 |
|-----|------|
| LEADERBOARD | 排行榜报表 |
| PLANTING | 认种统计报表 |
| ANALYTICS | 分析报表 |
| COMMUNITY | 社区统计报表 |
| SYSTEM_ACCOUNT | 系统账户报表 |
| INCOME_DETAIL | 收益明细报表 |
## 6. 索引策略
### 6.1 查询模式分析
| 查询场景 | 使用索引 | 频率 |
|---------|---------|------|
| 按报表编码查询快照 | idx_snapshot_code | 高 |
| 按时间范围查询快照 | idx_snapshot_generated | 高 |
| 按周期查询快照 | idx_snapshot_period | 中 |
| 按账户查询收益流水 | idx_sair_account | 高 |
| 按日期查询统计数据 | idx_pds_date, idx_cs_date | 高 |
### 6.2 复合索引建议
```sql
-- 高频查询: 按报表编码和周期查询最新快照
CREATE INDEX idx_snapshot_code_generated
ON report_snapshots(report_code, generated_at DESC);
-- 高频查询: 按账户和月份查询统计
CREATE INDEX idx_sams_account_month
ON system_account_monthly_stats(account_id, stat_month DESC);
-- 高频查询: 按日期和区域查询认种统计
CREATE INDEX idx_pds_date_region
ON planting_daily_stats(stat_date, province_code, city_code);
```
## 7. 数据保留策略
### 7.1 保留周期
| 表 | 保留周期 | 清理策略 |
|-----|---------|---------|
| report_snapshots | 90天 | 按 expires_at 清理 |
| report_files | 30天 | 按 expires_at 清理 |
| analytics_metrics | 365天 | 按 calculated_at 归档 |
| planting_daily_stats | 永久 | 按年归档 |
| system_account_income_records | 永久 | 按年归档 |
| report_events | 180天 | 按 occurred_at 清理 |
### 7.2 清理脚本
```sql
-- 清理过期快照
DELETE FROM report_snapshots
WHERE expires_at IS NOT NULL AND expires_at < NOW();
-- 清理过期文件
DELETE FROM report_files
WHERE expires_at IS NOT NULL AND expires_at < NOW();
-- 清理旧事件
DELETE FROM report_events
WHERE occurred_at < NOW() - INTERVAL '180 days';
```
## 8. Prisma Schema 映射
### 8.1 模型与表映射
| Prisma Model | 数据库表 | 主键映射 |
|--------------|---------|---------|
| ReportDefinition | report_definitions | definition_id |
| ReportSnapshot | report_snapshots | snapshot_id |
| ReportFile | report_files | file_id |
| AnalyticsMetric | analytics_metrics | metric_id |
| PlantingDailyStat | planting_daily_stats | stat_id |
| CommunityStat | community_stats | stat_id |
| SystemAccountMonthlyStat | system_account_monthly_stats | stat_id |
| SystemAccountIncomeRecord | system_account_income_records | record_id |
| ReportEvent | report_events | event_id |
### 8.2 关系映射
```prisma
// ReportSnapshot 1:N ReportFile
model ReportFile {
snapshot ReportSnapshot @relation(fields: [snapshotId], references: [id], onDelete: Cascade)
snapshotId BigInt @map("snapshot_id")
}
```
### 8.3 类型映射
| Prisma 类型 | PostgreSQL 类型 | 说明 |
|------------|----------------|------|
| BigInt | BIGSERIAL | 大整数主键 |
| String @db.VarChar(n) | VARCHAR(n) | 变长字符串 |
| String @db.Text | TEXT | 长文本 |
| Json | JSONB | JSON 二进制 |
| Decimal @db.Decimal(20,8) | DECIMAL(20,8) | 高精度数值 |
| DateTime | TIMESTAMP | 时间戳 |
| DateTime @db.Date | DATE | 日期 |
| Boolean | BOOLEAN | 布尔值 |
| String[] | VARCHAR(n)[] | 字符串数组 |