Fundamental_Analysis/docs/database_schema_design.md
Lv, Qi 21155bc4f8 feat(realtime): 接入前端实时报价并完善后端缓存
前端: 新增 RealTimeQuoteResponse 类型;新增 useRealtimeQuote Hook 并在报告页图表旁展示价格与时间戳(严格 TTL,无兜底)

FastAPI: 新增 GET /financials/{market}/{symbol}/realtime?max_age_seconds=.. 只读端点;通过 DataPersistenceClient 读取 Rust 缓存

Rust: 新增 realtime_quotes hypertable 迁移;新增 POST /api/v1/market-data/quotes 与 GET /api/v1/market-data/quotes/{symbol}?market=..;新增 DTO/Model/DB 函数;修正 #[api] 宏与路径参数;生成 SQLx 离线缓存 (.sqlx) 以支持离线构建

Python: DataPersistenceClient 新增 upsert/get 实时报价,并调整 GET 路径与参数

说明: TradingView 图表是第三方 websocket,不受我们缓存控制;页面数值展示走自有缓存通路,统一且可控。
2025-11-09 05:12:14 +08:00

145 lines
5.9 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.

# 数据库表结构设计 (`database_schema_design.md`)
## 1. 核心设计哲学与技术选型
经过深入讨论,我们确立了以**“为不同形态的数据建立专属的、高度优化的持久化方案”**为核心的设计哲学。这完美契合了项目追求稳定、健壮的“Rustic”风格。
我们的数据库技术栈将统一在 **PostgreSQL** 上,并通过其强大的扩展生态来满足特定的数据存储需求。
### 1.1. 时间序列数据: PostgreSQL + TimescaleDB
对于系统中最核心、数据量最大的**时间序列数据**(如财务指标、市场行情),我们明确采用 **TimescaleDB** 扩展。
- **为什么选择 TimescaleDB?**
- **解决性能瓶颈**: 它通过 **Hypertables (超表)** 机制,将一张巨大的时序表在物理上切分为按时间范围管理的小块 (Chunks)。这使得写入和基于时间的查询性能能够保持恒定的高速,不会随数据量增长而衰减。
- **支持稀疏与乱序数据**: 它的架构天然支持稀疏和乱序的数据写入,完美契合我们“有啥就存啥、随时补齐”的数据采集模式。
- **内置高级功能**: 它提供了强大的**持续聚合 (Continuous Aggregates)** 功能,可以高效地、自动化地将高频数据(如 Ticks降采样为分钟、小时、天等级别的聚合数据K线且查询速度极快。
- **零技术栈增加**: 它是一个 PostgreSQL 扩展,我们仍然使用标准 SQL 进行所有操作,无需引入和维护新的数据库系统。
### 1.2. 其他数据类型
- **生成式分析内容**: 使用标准的关系表,将结构化的元数据作为索引字段,将非结构化的文本存入 `TEXT` 字段。
- **静态与半静态数据**: 使用标准的关系表进行存储。
- **工作流与应用配置**: **优先使用 YAML 配置文件** (`config/analysis-config.yaml` 等) 来定义静态的工作流和分析模块。数据库仅用于存储需要通过管理界面动态修改的系统级配置。
- **执行过程元数据**: 使用标准的关系表来记录任务执行的结构化日志。
## 2. 详细 Schema 设计
### 2.1. 时间序列数据表
#### 2.1.1. `time_series_financials` (财务指标表)
```sql
-- 1. 创建标准的关系表
CREATE TABLE time_series_financials (
symbol VARCHAR(32) NOT NULL,
metric_name VARCHAR(64) NOT NULL, -- 标准化指标名 (e.g., 'roe', 'revenue')
period_date DATE NOT NULL, -- 报告期 (e.g., '2023-12-31')
value NUMERIC NOT NULL, -- 指标值
source VARCHAR(64), -- 数据来源 (e.g., 'tushare')
PRIMARY KEY (symbol, metric_name, period_date)
);
-- 2. 将其转换为 TimescaleDB 的超表
SELECT create_hypertable('time_series_financials', 'period_date');
COMMENT ON TABLE time_series_financials IS '存储标准化的、以时间序列格式存在的财务指标,由 TimescaleDB 管理';
```
#### 2.1.2. `daily_market_data` (每日市场数据表)
```sql
-- 1. 创建标准的关系表
CREATE TABLE daily_market_data (
symbol VARCHAR(32) NOT NULL,
trade_date DATE NOT NULL,
open_price NUMERIC,
high_price NUMERIC,
low_price NUMERIC,
close_price NUMERIC,
volume BIGINT,
pe NUMERIC,
pb NUMERIC,
total_mv NUMERIC, -- 总市值
PRIMARY KEY (symbol, trade_date)
);
-- 2. 将其转换为 TimescaleDB 的超表
SELECT create_hypertable('daily_market_data', 'trade_date');
COMMENT ON TABLE daily_market_data IS '存储每日更新的股价、成交量和关键估值指标,由 TimescaleDB 管理';
```
---
### 2.2. `analysis_results` (AI分析结果表)
```sql
CREATE TABLE analysis_results (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
symbol VARCHAR(32) NOT NULL,
module_id VARCHAR(64) NOT NULL, -- 分析模块ID (e.g., 'bull_case')
generated_at TIMESTAMTz NOT NULL DEFAULT NOW(),
model_name VARCHAR(64), -- 使用的AI模型
content TEXT NOT NULL, -- AI生成的完整文本
meta_data JSONB -- 用于存储token用量、耗时等元数据
);
COMMENT ON TABLE analysis_results IS '存储由AI大模型生成的分析报告文本';
CREATE INDEX idx_analysis_results_symbol_module ON analysis_results (symbol, module_id, generated_at DESC);
```
---
### 2.3. `company_profiles` (公司基本信息表)
```sql
CREATE TABLE company_profiles (
symbol VARCHAR(32) PRIMARY KEY, -- 标准化股票代码
name VARCHAR(255) NOT NULL, -- 公司名称
industry VARCHAR(255), -- 行业
list_date DATE, -- 上市日期
additional_info JSONB, -- 其他信息
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
COMMENT ON TABLE company_profiles IS '存储公司的基本、相对静态的信息';
```
---
### 2.4. `system_config` (系统配置表)
```sql
CREATE TABLE system_config (
config_key VARCHAR(255) PRIMARY KEY,
config_value JSONB NOT NULL,
description TEXT,
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
COMMENT ON TABLE system_config IS '存储可通过UI动态修改的系统级配置敏感信息(API Key)不应存储于此';
```
---
### 2.5. `execution_logs` (执行过程日志表)
```sql
CREATE TABLE execution_logs (
id BIGSERIAL PRIMARY KEY,
report_id UUID NOT NULL, -- 关联的报告ID
step_name VARCHAR(255) NOT NULL, -- 步骤名称
status VARCHAR(32) NOT NULL, -- 'running', 'completed', 'failed'
start_time TIMESTAMPTZ NOT NULL,
end_time TIMESTAMPTZ,
duration_ms INTEGER,
token_usage JSONB, -- { "prompt": 100, "completion": 200 }
error_message TEXT,
log_details JSONB
);
COMMENT ON TABLE execution_logs IS '记录报告生成过程中每个步骤的结构化日志';
CREATE INDEX idx_execution_logs_report_id ON execution_logs (report_id);
```