# 数据模型文档 ## 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)[] | 字符串数组 |